2015-01-23 5 views
2

Хорошо, поэтому я пытаюсь использовать регулярное выражение для соответствия экземплярам символа только в том случае, если он не был экранирован (с обратной косой чертой) и решил использовать отрицательный внешний вид, за примерно так:Регулярное выражение для соответствия только необработанным символам

(?<!\\)[*] 

Это преуспевает и терпит неудачу как ожидается, со строками, такие как foo* и foo\* соответственно.

Однако он не работает для строк, таких как foo\\*, i.e - где специальному символу предшествует обратная косая черта, сбрасывающая другую обратную косую черту (escape-последовательность, которая сама экранирована).

Можно ли использовать негативный внешний вид (или какой-либо другой метод), чтобы пропустить специальные символы, только если им предшествует нечетное число обратных косых черт?

+2

Какой язык вы работаете? –

+0

[Дубликат] (https://stackoverflow.com/questions/5937241/regular-expression-to-match-unescaped-special-characters-only). Кроме того, вы не сказали нам язык, который вы используете, и вы определенно не искали не менее 20 секунд, чтобы найти решение. –

+0

@ AvinashRaj в моем случае Swift (или, более конкретно, я использую 'NSRegularExpression'), похоже, что у него нет никаких функций регулярного выражения, поэтому я не думал, что нужно упоминать. @rac вы определенно не искали более 20 секунд в дубликате, который вы опубликовали, так как это не касается моего точного дела; i.e - его escape-последовательность не может использоваться для того, чтобы сбежать. – Haravikk

ответ

4

Я ve нашел следующее решение, которое работает для NSRegularExpression, но также работает во всех реализациях регулярных выражений. Я пробовал, что поддерживает отрицательные образы:

(?<!\\)(?:(\\\\)*)[*] 

В этом случае вторая несогласованная скобка соответствует любым парам обратных косых черт, эффективно устраняя их, после чего отрицательный внешний вид может сравнивать любые оставшиеся (нечетные) обратные слэши, как ожидалось.

+0

Точно, что я был после, хорошая работа! – singe3

+0

Это работает, но не может совпадать с невыпадающими обратными косыми чертами - вы знаете, как его расширить, чтобы это можно было сделать? – Cocowalla

1

Невозможно решить эту проблему. Единственный способ, чтобы соответствовать экранированным символам первыми, чтобы избежать их и найти неэкранированные символы:

вы можете изолировать неэкранированный символ из результата с захватом группой:

(?:\\.)+|(\*) 

или с \K (PCRE/Perl/рубин) функция, которая удаляет все слева от результата:

(?:\\.)*\K\* 

или с использованием возвратов управления глаголами (PCRE/Perl), чтобы пропустить экранированные символы:

(?:\\.)+(*SKIP)(*FAIL)|\* 

Единственный случай, вы можете использовать это с просмотром назад в рамках .net, что позволяет неограниченную длину: 'назад

(?<!(?:[^\\]|\A)(?:\\\\)*\\)\* 

или в более ограниченном объеме с Java:

(?<!(?:[^\\]|\A)(?:\\\\){0,1000}\\)\* 
+0

Хм, на самом деле я просто попробовал '(? Haravikk

Смежные вопросы