选择字符串中的前X个数字,并用Character替换每个数字

时间:2019-03-20 15:53:42

标签: android regex kotlin

我正在尝试用*替换字符串中的所有数字。

现在我有这个

val regex = "^[\\d+].{8}"
val pattern = Pattern.compile(regex)
code = code.replace(pattern.toRegex(), "*** *** *")

这有点奏效,但是我想拥有*而不是"*** *** *" 因此我们的想法是替换单个数字而不是一个块。

示例字符串:

  

123 456 789 0

2 个答案:

答案 0 :(得分:1)

可读的正则表达式方法是匹配从字符串开头到第8位的任意数量的字符,然后将匹配项传递给一个块,并用数字模式替换第二次:

val s = "123 456 789 0"
val regex = """^(?:\D*\d){8}""".toRegex()
println(s.replace(regex) { it.value.replace(Regex("""\d"""), "*") })
// => *** *** **9 0

请参见Kotlin demo online

^(?:\D*\d){8}正则表达式匹配

  • ^-字符串开头
  • (?:\D*\d){8}-8次重复:
    • \D*-除数字外的0个或更多字符
    • \d-一个数字。

仅供参考,您可以使用具有八个捕获组的硬编码版本来实现相同的目的,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*")如果输入字符串中始终有8位数字。

答案 1 :(得分:0)

您可能只想重复n次,直到替换了所需的字符数,而不是正则表达式。使用功能性方法,您可以执行以下操作:

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)
}

然后:

println("123 456 789 0".redact()) // *** *** **9 0