Regex.Replace — пропускать строки, которые являются частью более длинной строки

#c# #regex #replace

#c# #регулярное выражение #заменить

Вопрос:

Мне нужно заменить список числовых строк в текстовом файле. Однако, если строка является частью другой числовой строки, ее не следует заменять: Строка, подлежащая замене: 111111 Строка замены: В МАСКЕ

 Text file:
111111
 111111.text text
text text111111 text text
a111111
2111111
111111a
1111112
a111111a

Expected result:
MASKED
 MASKED.text text
text textMASKED text text
aMASKED
2111111 -> Character 2 prevents masking
MASKEDa
1111112 -> Character 2 prevents masking
aMASKEDa
  

Это мой код:

 inputText = Regex.Replace(inputText, "(?<![0-9])"   stringToMask   "(?<![0-9])", "####MASKED####");
  

Этот код просто пропускает все и не выполняет никакой маскировки.

Комментарии:

1. Не должно ли второе (?<![0-9]) быть (?![0-9]) — негативный взгляд в будущее?

2. что сказал sh54. Он заслуживает оценки 🙂

3. @Henk, нет, ты не можешь. D было бы [^0-9] . ! Относится к утверждению look behind (?<! ...) .

4. sh54 — это сработало. Я был бы рад выбрать ваш ответ, если вы его создадите.

Ответ №1:

Вы можете использовать MatchEvaluator http://www.dotnetperls.com/regex-replace для выполнения замены на условие. Чтобы решить, заменять заготовку или нет, вы можете добавить первую и последнюю букву в соответствии с шаблоном, разделить строку по этому шаблону и проанализировать первый и последний символы.

Комментарии:

1. также добавьте Regexp.Escape к вашему шаблону, он может содержать специальные символы внутри

2. Я изучал это, потому что мне интересно добавить еще несколько проверок для замены. Я хотел бы иметь список предопределенных строк, присутствие которых будет подавлять действие замены. Например, в строке «amount=111111» наличие ‘amount=’ должно остановить совпадение. Я посмотрел на опубликованный вами пример и несколько других и не понял, как это можно сделать. Делегат принимает только совпадение, поэтому он не может проверить, что идет перед ним.

3. используйте Regex.Replace(входной текст, «.?» stringToMask «.?», «#### МАСКИРОВАННЫЙ ####»); Вы получите совпадение, которое вам нужно, с 1 дополнительным символом в начале и в конце. Чем вы можете разделить строку на 11111, первый элемент будет первым символом, предпоследний. Когда вы закончите синтаксический анализ, вы должны добавить первый и последний символ в заменяемую строку.

4. Спасибо. К сожалению, это означает, что я не могу использовать это для цели, которую я объяснил выше.

Ответ №2:

Если я правильно понимаю вашу проблему, следующее регулярное выражение должно работать:

 (?<!d)111111(?!d)
  

Он использует как отрицательное утверждение lookbehind, так и отрицательное утверждение lookahead.

Вот рабочий пример.

Вывод:

 MASKED
 MASKED.text text
text textMASKED text text
aMASKED
2111111
MASKEDa
1111112
aMASKEDa