I would like help to create an input masking using find and replace regexes for the following use case:
The user types 11 digits of his identification number and the output will be formatted with this pattern:
\d\d\d.\d\d\d.\d\d\d-\d\d
First attempt
Find: (\d{3})(\d{3})(\d{3})(\d{2})
Replace: $1.$2.$3-$4
This only works after the user types all the 11 digits. However, I want the dots and dashes to appear while the user types.
Second attempt
Find: (\d{1,3})(\d{1,3})(\d{1,3})(\d{1,2})
Replace: $1.$2.$3-$4
As soon as the user types the fourth digit, but the result ends up being like this \d.\d.\d-\d
Third attempt
Find: (\d{3})(\d{0,3})(\d{0,3})(\d{0,2})
Replace: $1.$2.$3-$4
As soon as the user types the third digit, but the result ends up being like this \d\d\d\..-
Code:
A brief description of the code:
fun transformation(input: String, findRegex: String, replaceRegex: String): String =
input.replace(findRegex.toRegex(), replaceRegex)
fun main() {
val input = "01121212"
val findRegex = """(\d{3})(\d{3})(\d{3})(\d{2})"""
val replaceRegex = """$1.$2.$3-$4"""
val result = transformation(input, findRegex, replaceRegex)
println(result)
}
Full code can be found here: https://gitlab.com/pertence/masked-textinput
You can use
fun transformation(input: String, findRegex: String, replaceRegex: String): String =
input.replace("""\D+""".toRegex(), "").replace(findRegex.toRegex(), {
it.groupValues[1].toString() +
(if (!it.groupValues[2].isNullOrEmpty()) ".${it.groupValues[2].toString()}" else "") +
(if (!it.groupValues[3].isNullOrEmpty()) ".${it.groupValues[3].toString()}" else "") +
(if (!it.groupValues[4].isNullOrEmpty()) "-${it.groupValues[4].toString()}" else "")
})
fun main(args: Array<String>) {
val input = "0112121234" // 011.212.123-4
// val input = "011" // 011
// val input = "01121212" // 011.212.12
// val input = "011212" // 011.212
// val input = "01121" // 011.21
// val input = "0112" // 011.2
val findRegex = """^(\d{3})(\d{1,3})?(\d{1,3})?(\d{1,2})?$"""
val replaceRegex = """$1.$2.$3-$4"""
val result = transformation(input, findRegex, replaceRegex)
println(result)
}
See the online Kotlin demo.
NOTES:
.replace("""\D+""".toRegex(), "")
- removes all non-digits.replace(findRegex.toRegex(), { it.groupValues[1].toString() + (if (!it.groupValues[2].isNullOrEmpty()) ".${it.groupValues[2].toString()}" else "") + (if (!it.groupValues[3].isNullOrEmpty()) ".${it.groupValues[3].toString()}" else "") + (if (!it.groupValues[4].isNullOrEmpty()) "-${it.groupValues[4].toString()}" else "") })
- matches a pattern and replaces the match with different replacements depending on whether a group matched or not.The regex is
^(\d{3})(\d{1,3})?(\d{1,3})?(\d{1,2})?$
See the regex demo. Details:
^
- start of string(\d{3})
- Group 1: three digits(\d{1,3})?
- an optional Group 2 that matches one, two or three digits(\d{1,3})?
- an optional Group 3 that matches one, two or three digits(\d{1,2})?
- an optional Group 4 that matches one or two digits$
- end of string.