Reputation: 5846
I'm trying to replace all digits in a string with an *.
Right now i have this
val regex = "^[\\d+].{8}"
val pattern = Pattern.compile(regex)
code = code.replace(pattern.toRegex(), "*** *** *")
It kinda works, but i want to have *
instead of "*** *** *"
so the idea is to replace single digits instead of a block.
example string:
123 456 789 0
Upvotes: 1
Views: 2589
Reputation: 626758
A readable regex approach is to match any amount of chars from the start of the string up to the 8th digit and then pass the match to a block and replace the second time with a digit pattern:
val s = "123 456 789 0"
val regex = """^(?:\D*\d){8}""".toRegex()
println(s.replace(regex) { it.value.replace(Regex("""\d"""), "*") })
// => *** *** **9 0
See the Kotlin demo online
The ^(?:\D*\d){8}
regex matches
^
- string start(?:\D*\d){8}
- 8 repetitions of:
\D*
- 0 or more chars other than digits\d
- a digit.Just FYI, you may achieve the same with a hardcoded version with eight capturing groups, s.replace("""^(\D*)\d(\D*)\d(\D*)\d(\D*)\d(\D*)\d(\D*)\d(\D*)\d(\D*)\d""".toRegex(), "$1*$2*$3*$4*$5*$6*$7*$8*")
if you always have 8 digits in the input string.
Upvotes: 2
Reputation: 134664
Rather than a regex, you probably just want to iterate n
number of times until you've replaced the desired number of characters. Using a functional approach you could do something like:
fun String.redact(numDigits:Int = 8): String {
val charArray = toCharArray()
charArray.withIndex()
.filter { (_, char) -> Character.isDigit(char) }
.take(numDigits)
.forEach { (index, _) -> charArray[index] = '*' }
return String(charArray)
}
Then:
println("123 456 789 0".redact()) // *** *** **9 0
Upvotes: 0