c # заменить выражение «кроме если» - PullRequest
0 голосов
/ 04 июня 2018

Я пытаюсь изменить подстроки строки, например,

this is some weird text that I want to format text for some ='custom text' content "text" ="text"...

Результат должен быть

this is some weird sentence that I want to format sentence for some ='custom text' content "sentence" ="text"...

Я хочу заменить все вхождения text на sentence, ЗА ИСКЛЮЧЕНИЕМ, если вхождение содержится в ='...' или ="...".

Обработка указанного в ТОЧНОСТИ вхождения (т. Е. ="test" или ='test') довольно проста, но я застрял в содержащейся части....

Я думал о Regex, но я недостаточно знаком с ними, чтобы добиться успеха ...

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Я знаю, что это не так, но вы разрабатываете язык .На самом деле очень простой язык обработки строк.Поэтому подходите к проблеме так же, как к разработке языка программирования.Ваш рабочий процесс должен быть:

  • Lex входной строки в последовательность токенов
  • Преобразовать последовательность токенов, используя ваше правило
  • Преобразовать последовательность токенов обратно в строку

Первый - сложный, но не такой сложный.Вы можете сделать это.

Ваш лексер может быть смоделирован как конечный автомат .То есть:

  • мы отслеживаем «текущее состояние»
  • мы обрабатываем каждый символ, по одному
  • обработка зависит только от двух вещей: чточто это был за символ, и в каком состоянии мы находимся?
  • . Это порождает две вещи: (1) новое текущее состояние (возможно, такое же, как старое состояние) и (2) решение, да или нет, мына границе токена?
  • Если мы находимся на границе токена, то мы добавляем новый токен в список токенов.

Когда мы обработали каждый символ, мыполучил список токенов.

Давайте рассмотрим некоторые типичные правила лексера для вашего примера.Мы всегда начинаем с того, что говорим:

  • Есть четыре состояния: Нормальное, Равное, Одиночное и Двойное
  • Мы начинаем в Нормальном состоянии

Сейчасскажи, что делать в каждом состоянии:

  • В нормальном состоянии, если вы получаете =, завершите текущий токен, если он есть, запустите новый токен Equals, добавьте = вэто, и перейдите в состояние равных.В противном случае добавьте символ к текущему токену, если он есть, или создайте новый токен Normal, если его нет.
  • В состоянии Equals завершите текущий токен.Если вы получили ', перейдите в состояние Single и создайте токен Single.Если вы получите ", создайте Двойной токен и перейдите в Двойное состояние.Если вы получите =, создайте токен Equals и оставайтесь в состоянии Equals.В противном случае создайте токен Normal и вернитесь в нормальное состояние.Добавьте символ к текущему токену.
  • В одиночном состоянии добавьте символ к текущему токену.Если вы получили ', перейдите в нормальное состояние.В противном случае оставайтесь в одиночном состоянии.
  • Аналогично для двойного состояния.
  • Если у вас закончились символы, завершите текущий токен.

И так далее.Вы видите, как это происходит.У нас есть очень простая маленькая машинка, которая просто просматривает все символы и решает, какой текст мы видели до сих пор, и нужно ли разбивать его на этом этапе или нет.Вы получите список токенов, где каждый токен имеет часть вашей строки.

Теперь вы можете выполнять поиск и замену на своих токенах Normal, зная, что вы не будете делать замены ни на одном из ваших токенов Single, Double или Equals.

Затем поместите замененные строкивместе в том же порядке, и все готово.

0 голосов
/ 04 июня 2018
(?<!\=\s*?(\'[^']*)|(\"[^"]*))text

заменить на sentence

Это делает отрицательный взгляд назад переменной длины для =' (и затем не другого апострофа) .. То же самое с ".По сути, он отклонит совпадение, если обнаружит, что за этим стоит.

Это все еще относительно хрупкое и может быть взорвано экранированными или несоответствующими кавычками, но в зависимости от ваших данных это может быть приемлемо.Это, безусловно, будет работать под наблюдением человека.

Если строки типа Data='Bob said "Mary's not here yet" text' представляют серьезную проблему, я бы пропустил подход регулярных выражений.

Проверьте здесь, чтобы увидеть его: (Контекстная вкладка)

...