diff --git a/CHANGELOG b/CHANGELOG
index 66d1dbda1..057ab2f7c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
KeePassDX(3.3.0)
* Quick search and dynamic filters #163 #462 #521
* Keep search context #1141
+ * Search with regular expression #175
KeePassDX(3.2.0)
* Manage data merge #840 #977
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/search/SearchHelper.kt b/app/src/main/java/com/kunzisoft/keepass/database/search/SearchHelper.kt
index 51e190e99..c72eac5c7 100644
--- a/app/src/main/java/com/kunzisoft/keepass/database/search/SearchHelper.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/database/search/SearchHelper.kt
@@ -207,12 +207,21 @@ class SearchHelper {
private fun checkSearchQuery(stringToCheck: String, searchParameters: SearchParameters): Boolean {
/*
// TODO Search settings
- var regularExpression = false
var removeAccents = true <- Too much time, to study
*/
- return stringToCheck.isNotEmpty()
- && stringToCheck.contains(
- searchParameters.searchQuery, !searchParameters.caseSensitive)
+ if (stringToCheck.isEmpty())
+ return false
+ return if (searchParameters.isRegex) {
+ val regex = if (searchParameters.caseSensitive) {
+ searchParameters.searchQuery.toRegex(RegexOption.DOT_MATCHES_ALL)
+ } else {
+ searchParameters.searchQuery
+ .toRegex(setOf(RegexOption.DOT_MATCHES_ALL, RegexOption.IGNORE_CASE))
+ }
+ regex.matches(stringToCheck)
+ } else {
+ stringToCheck.contains(searchParameters.searchQuery, !searchParameters.caseSensitive)
+ }
}
}
}
diff --git a/app/src/main/java/com/kunzisoft/keepass/database/search/SearchParameters.kt b/app/src/main/java/com/kunzisoft/keepass/database/search/SearchParameters.kt
index 7a4322298..241f18e50 100644
--- a/app/src/main/java/com/kunzisoft/keepass/database/search/SearchParameters.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/database/search/SearchParameters.kt
@@ -28,6 +28,7 @@ import android.os.Parcelable
class SearchParameters() : Parcelable{
var searchQuery: String = ""
var caseSensitive = false
+ var isRegex = false
var searchInTitles = true
var searchInUsernames = true
diff --git a/app/src/main/java/com/kunzisoft/keepass/view/SearchFiltersView.kt b/app/src/main/java/com/kunzisoft/keepass/view/SearchFiltersView.kt
index 1ecfdc0df..f74906dda 100644
--- a/app/src/main/java/com/kunzisoft/keepass/view/SearchFiltersView.kt
+++ b/app/src/main/java/com/kunzisoft/keepass/view/SearchFiltersView.kt
@@ -24,6 +24,7 @@ class SearchFiltersView @JvmOverloads constructor(context: Context,
private var searchNumbers: TextView
private var searchCurrentGroup: CompoundButton
private var searchCaseSensitive: CompoundButton
+ private var searchRegex: CompoundButton
private var searchTitle: CompoundButton
private var searchUsername: CompoundButton
private var searchPassword: CompoundButton
@@ -41,6 +42,7 @@ class SearchFiltersView @JvmOverloads constructor(context: Context,
return field.apply {
this.searchInCurrentGroup = searchCurrentGroup.isChecked
this.caseSensitive = searchCaseSensitive.isChecked
+ this.isRegex = searchRegex.isChecked
this.searchInTitles = searchTitle.isChecked
this.searchInUsernames = searchUsername.isChecked
this.searchInPasswords = searchPassword.isChecked
@@ -60,6 +62,7 @@ class SearchFiltersView @JvmOverloads constructor(context: Context,
mOnParametersChangeListener = null
searchCurrentGroup.isChecked = value.searchInCurrentGroup
searchCaseSensitive.isChecked = value.caseSensitive
+ searchRegex.isChecked = value.isRegex
searchTitle.isChecked = value.searchInTitles
searchUsername.isChecked = value.searchInUsernames
searchPassword.isChecked = value.searchInPasswords
@@ -96,6 +99,7 @@ class SearchFiltersView @JvmOverloads constructor(context: Context,
searchNumbers = findViewById(R.id.search_numbers)
searchCurrentGroup = findViewById(R.id.search_chip_current_group)
searchCaseSensitive = findViewById(R.id.search_chip_case_sensitive)
+ searchRegex = findViewById(R.id.search_chip_regex)
searchTitle = findViewById(R.id.search_chip_title)
searchUsername = findViewById(R.id.search_chip_username)
searchPassword = findViewById(R.id.search_chip_password)
@@ -125,6 +129,10 @@ class SearchFiltersView @JvmOverloads constructor(context: Context,
searchParameters.caseSensitive = isChecked
mOnParametersChangeListener?.invoke(searchParameters)
}
+ searchRegex.setOnCheckedChangeListener { _, isChecked ->
+ searchParameters.isRegex = isChecked
+ mOnParametersChangeListener?.invoke(searchParameters)
+ }
searchTitle.setOnCheckedChangeListener { _, isChecked ->
searchParameters.searchInTitles = isChecked
mOnParametersChangeListener?.invoke(searchParameters)
diff --git a/app/src/main/res/drawable/ic_regex_white_24dp.xml b/app/src/main/res/drawable/ic_regex_white_24dp.xml
new file mode 100644
index 000000000..ffe6c14a0
--- /dev/null
+++ b/app/src/main/res/drawable/ic_regex_white_24dp.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/view_search_filters.xml b/app/src/main/res/layout/view_search_filters.xml
index 1c0a75e20..5918a0d6e 100644
--- a/app/src/main/res/layout/view_search_filters.xml
+++ b/app/src/main/res/layout/view_search_filters.xml
@@ -180,6 +180,14 @@
style="@style/KeepassDXStyle.Chip.Filter.Icon"
android:text="@string/case_sensitive"
app:closeIcon="@drawable/ic_case_sensitive_white_24dp" />
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9492f365f..bbd9176ed 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -107,6 +107,7 @@
Algorithm
Current group
Case sensitive
+ Regular expression
Debit / Credit Card
Holder
Number
diff --git a/art/ic_regex.svg b/art/ic_regex.svg
new file mode 100644
index 000000000..7859cbb1e
--- /dev/null
+++ b/art/ic_regex.svg
@@ -0,0 +1,97 @@
+
+
+
+
diff --git a/fastlane/metadata/android/en-US/changelogs/98.txt b/fastlane/metadata/android/en-US/changelogs/98.txt
index 8256838e7..a92de5b54 100644
--- a/fastlane/metadata/android/en-US/changelogs/98.txt
+++ b/fastlane/metadata/android/en-US/changelogs/98.txt
@@ -1,2 +1,3 @@
* Quick search and dynamic filters #163 #462 #521
- * Keep search context #1141
\ No newline at end of file
+ * Keep search context #1141
+ * Search with regular expression #175
\ No newline at end of file
diff --git a/fastlane/metadata/android/fr-FR/changelogs/98.txt b/fastlane/metadata/android/fr-FR/changelogs/98.txt
index 00ab98597..d34f81b6c 100644
--- a/fastlane/metadata/android/fr-FR/changelogs/98.txt
+++ b/fastlane/metadata/android/fr-FR/changelogs/98.txt
@@ -1,2 +1,3 @@
* Recherche rapide et filtres dynamiques #163 #462 #521
- * Garde le contexte de recherche #1141
\ No newline at end of file
+ * Garde le contexte de recherche #1141
+ * Recherche avec expression régulière #175
\ No newline at end of file