2015-09-17 2 views
0

Предположим, у меня есть следующая строка.Java Регулярное выражение Отрицательный взгляд вперед Поиск неправильного соответствия

create or replace package test as 
-- begin null; end;/ 
end; 
/

Я хочу, чтобы регулярное выражение, которое будет найти точку с запятой не предшествует набору "--" двойных черточек на одной и той же линии. Я использую следующий шаблон "(?!--.*);", и я все еще получаю совпадения для двух точек с запятой на 2-й строке.

Я чувствую, что мне что-то недостает негативного взгляда, но я не могу понять, что.

+0

Пожалуйста, разместите полный код. Разделяете ли вы многострочную строку? –

+0

Вы хотите совместить вторую точку с запятой на второй строке или только третью? – whrrgarbl

ответ

0

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

^(?!--).*(;)

Example

Я только сделал несколько изменений от вашего регулярного выражения:

  1. Multi-li Режим п, поэтому мы можем использовать ^ и $ и поиск по линии

  2. ^ в начале, чтобы указать начало строки

  3. .* между отрицательным предпросмотром и точкой с запятой, потому что в противном случае с первым изменением его будет пытаться соответствовать что-то вроде ^;, который неправильно

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

+0

Спасибо, это то, чего мне не хватало. Я на самом деле думал, что многострочный означает, что он будет рассматривать все строки не так, чтобы он смотрел на него по очереди. – Shawn

+0

Yup, если вы хотите рассмотреть всю строку сразу, это глобальный режим. Если бы вы сделали это таким образом, я бы подумал, что вам придется заменить '^' на '\ n', но многострочный, казалось, имел больше смысла для вашего ввода :) – whrrgarbl

+0

Что делать, если тире тире не в начале строка, например 'foo-end;'? Тогда ваше регулярное выражение не будет работать. и btw, ваше регулярное выражение такое же, как '^ (?! -). *;' – Bohemian

0

Прежде всего, вам нужен отрицательный lookbehind (?<!), а не отрицательный lookahead (?!), так как вы хотите проверить, что стоит за вашим потенциальным совпадением.

Даже при этом вы не сможете использовать отрицательный lookbehind в своем случае, так как механизм регулярных выражений Java не поддерживает переменную длину lookbehind. Это означает, что вам нужно точно знать, сколько персонажей должно выглядеть позади вашего потенциального соответствия для его работы.

Сказанное в этом случае не будет проще в вашем случае просто разделить вашу строку на возврат строки/каретки, а затем удалить строку, начинающуюся с «-»?

+0

Каким образом примеры на http://www.ocpsoft.org/opensource/guide-to-regular-expressions-in-java-part-2/ показывают отрицательный результат, соответствующий тому, что находится за матчем. – Shawn

+0

Я видел ваш пример, и на сайте есть явная и ошибка. «Кража была серьезным инцидентом» с «кражей». * Инцидент. * « –

0

Причины "(?!--.*);" не работает потому, что негативный взгляд упреждающим утверждать, что при расположении перед ;, что следующие два символом является --, какие из (; всегда не --).

В Java, чтобы соответствовать ;, который не имеет -- где-нибудь перед ним:

"\\G(((?<!--)[^;])*);" 

Чтобы увидеть это в действии, используя replaceAll() вызов:

String s = "foo; -- begin null; end;"; 
s = s.replaceAll("\\G(((?<!--)[^;])*);", "$1!"); 
System.out.println(s); 

Выход:

foo! -- begin null; end; 

Показаны, что только полуколоны b перед двойным тире совпадают.

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