#r #regex #gsub #regex-group #data-masking
#r #регулярное выражение #gsub #группа регулярных выражений #маскировка данных
Вопрос:
a <- c("this is a number 9999333333 and i got 12344")
Как я мог бы заменить число, превышающее 5 цифр, дополнительными цифрами, равными «X»
Ожидаемый результат:
"this is a number 99993XXXXX and i got 12344"
Код, который я пробовал:
gsub("(.{5}).*", "X", a)
Ответ №1:
Вы можете использовать gsub
с регулярным выражением PCRE:
(?:G(?!^)|(?<!d)d{5})Kd
Смотрите демонстрацию регулярных выражений. Подробные сведения:
(?:G(?!^)|(?<!d)d{5})
— конец предыдущего успешного совпадения (G(?!^)
) или (|
) местоположение, которому не предшествует цифра ((?<!d)
), а затем любые пять цифрK
— оператор сброса соответствия, отбрасывающий весь текст, который был сопоставлен до сих порd
— цифра.
Смотрите демонстрацию R:
a <- c("this is a number 9999333333 and i got 12344")
gsub("(?:\G(?!^)|(?<!\d)\d{5})\K\d", "X", a, perl=TRUE)
## => [1] "this is a number 99993XXXXX and i got 12344"
Комментарии:
1. Спасибо, если я хочу заменить X после первых 2 цифр на числа, превышающие 5 цифр, как я могу это изменить, например: «это число 99XXXXXXXX, и я получил 12344»
2. @prog Затем используйте
gsub("(?:\G(?!^)|(?<!\d)\d{2}(?=\d{4}))\K\d", "X", a, perl=TRUE)
.(?=d{4})
Положительный прогноз требует, чтобы еще четыре цифры появлялись сразу после первых двух.
Ответ №2:
gsubfn
в пакете gsubfn это похоже на gsub
за исключением того, что строка замены может быть функцией, которая вводит группы захвата и выводит замену на соответствие. Функция может быть необязательно выражена в виде формулы, как мы делаем здесь.
Регулярное выражение (d{5})
сопоставляет и фиксирует 5 цифр и (d )
сопоставляет и фиксирует оставшиеся цифры. Две группы захвата загружаются в функцию и вставляются обратно вместе, за исключением того, что каждый символ во второй заменяется на X
. r"{...}"
это обозначение для строковых литералов, введенное в R 4.0, которое устраняет необходимость использования двойной обратной косой черты для обозначения обратной косой черты в строковом литерале.
library(gsubfn)
gsubfn(r"{(d{5})(d )}", ~ paste0(x, gsub(".", "X", y)), a)
## [1] "this is a number 99993XXXXX and i got 12344"
Если мы заменим первый аргумент регулярным выражением r"{(d{2})(d{4,})}"
, то оно заменит все цифры, кроме первых двух, при условии, что их не менее 6 цифр.
Ответ №3:
Альтернативный способ, не использующийся gsub
для замены чисел, превышающих 5 цифр в тексте, состоит в том, чтобы разделить строку на strsplit
, проверить, есть ли только цифры, и объединить substr
и a strrep
:
paste(lapply(strsplit(a, " ")[[1]], function(x) {
if(!grepl("\D", x)) {
paste0(substr(x, 1, 5), strrep("X", pmax(0, nchar(x)-5)))
} else {x}}), collapse = " ")
#[1] "this is a number 99993XXXXX and i got 12344"
Заменить X после первых 2 цифр для чисел, превышающих 5 цифр:
paste(lapply(strsplit(a, " ")[[1]], function(x) {
if(!grepl("\D", x) amp; nchar(x) > 5) {
paste0(substr(x, 1, 2), strrep("X", pmax(0, nchar(x)-2)))
} else {x}}), collapse = " ")
#[1] "this is a number 99XXXXXXXX and i got 12344"