Я пытаюсь заменить все цифры в строке на *.
Прямо сейчас у меня есть это
val regex = "^[\\d+].{8}"
val pattern = Pattern.compile(regex)
code = code.replace(pattern.toRegex(), "*** *** *")
Вроде работает, но я хочу * вместо "*** *** *"
поэтому идея состоит в том, чтобы заменить отдельные цифры вместо блока.
пример строки:
123 456 789 0
Я хочу заменить каждое вхождение цифры на *, пока я не заменю 8 цифр, моя окончательная строка должна выглядеть как «*** *** *89 0»
А если цифр меньше 8?
Строка всегда будет иметь один и тот же размер
Однако в примере вы не заменяете 8 цифр, вы заменяете только 7. В любом случае, (0 until 7).forEach { raw = raw.replaceFirst("\\d".toRegex(), "*") } значительно менее подвержен ошибкам и также поддерживает разные форматы. И может быть немного быстрее. К сожалению, метод замены в настоящее время не имеет счетчика. Я не могу придумать какое-либо регулярное выражение, которое делает это точно, когда оно включает пробелы, без замены полного счета вручную. Но если стиль строки всегда один и тот же, просто "*** *** *" + rex.substring(9).
Вместо регулярного выражения вы, вероятно, просто захотите повторить 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
Читаемый подход регулярного выражения состоит в том, чтобы сопоставить любое количество символов от начала строки до 8-й цифры, а затем передать совпадение в блок и заменить второй раз цифровым шаблоном:
val s = "123 456 789 0"
val regex = """^(?:\D*\d){8}""".toRegex()
println(s.replace(regex) { it.value.replace(Regex("""\d"""), "*") })
// => *** *** **9 0
См. Демонстрация Котлина онлайн
Регулярное выражение ^(?:\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 цифр во входной строке.
Возможно, я вас неправильно понял, но если вы хотите заменить только один, есть
replaceFirst. Кроме того, ваше текущее регулярное выражение соответствует любому количеству цифр, за которым следует любой символ 8 раз. Если вы хотите заменить только цифры, вам нужно добавить группу захвата, чтобы исключить остальные. т.е."""^\d*(.{8})"""заменено на*$1"