2012-02-25 3 views
5

Я использую регулярное выражение для поиска:Regex LOOKAHEAD

test:? 

Вслед за любым символом до он не достигнет следующей:

test:? 

Теперь, когда я запускаю это регулярное выражение я сделал:

((?:test:\?)(.*)(?!test:\?)) 

Об этом тексте:

test:?foo2=bar2&baz2=foo2test:?foo=bar&baz=footest:?foo2=bar2&baz2=foo2 

Я ожидал получить:

test:?foo2=bar2&baz2=foo2 

test:?foo=bar&baz=foo 

test:?foo2=bar2&baz2=foo2 

Но вместо того, чтобы он соответствовал всем. Кто-нибудь, у кого больше опыта в регулярном выражении, знает, где я ошибся? Я использовал регулярные выражения для сопоставления шаблонов, но это мой первый опыт поиска/опережения.

Заранее спасибо за любую помощь/советы/указатели :-)

+0

Вы просто желая разделить на 'тест:?'? Если да, то ваша среда обеспечит способ сделать это без регулярных выражений. –

ответ

4

Я думаю, вы могли бы изучить жадную версию.
(расширенный)

(test:\? (?: (?!test:\?)[\s\S])*)

+0

Спасибо. Это сработало отлично, и я узнал больше о синтаксисе. – james

-1

Вы, вероятно, хотите ((?:test:\?)(.*?)(?=test:\?)), хотя вы не сказали нам, что язык вы используете для привода регулярных выражений.

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

В зависимости от того, на каком языке вы используете это, вам, вероятно, придется сопоставлять, затем нарезать строку, затем снова совместить или вызвать некоторую специфичную для языка функцию типа match_all.

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

test:[?](.*?)test:[?] 
+1

Если вы собираетесь принять такой подход, вам нужно изменить '?' 'На'? = '. – ruakh

+0

@ruakh Право. Изменено, спасибо. – Borealid

+1

-1, необходим lookahead. Без него любое другое требуемое совпадение не будет соответствовать, потому что 'test:' уже был использован. – Qtax

0

три вопроса:

  • (?!) является условное выражение. Вместо этого вы хотите (?=), требуя, чтобы следующий: test:?.

  • .* жадность; вы хотите, чтобы это было не жадным, чтобы вы захватили только первый кусок.

  • Вам также нужен последний кусок, поэтому вы хотите совместить $, а также в конце.

Конечный результат:

(?:test:\?)(.*?)(?=test:\?|$) 

Я также удалил внешнюю группу, не видя смысла в нем. Все двигатели RE, о которых я знаю, позволяют вам получить доступ к группе 0 в качестве полного соответствия или какой-либо другой такой способ (хотя, возможно, не при поиске всех совпадений). Вы можете вернуть его, если вам нужно.

(Это работает в PCRE, не уверен, что если он будет работать с регулярными выражениями POSIX, так как я не привык работать с ними.)

Если вы просто хотите разделить на test:?, хотя регулярные выражения являются неправильным инструментом. Разделите строки, используя встроенную поддержку вашего языка для таких вещей.

Python:

>>> re.findall('(?:test:\?)(.*?)(?=test:\?|$)', 
... 'test:?foo2=bar2&baz2=foo2test:?foo=bar&baz=footest:?foo2=bar2&baz2=foo2') 
['foo2=bar2&baz2=foo2', 'foo=bar&baz=foo', 'foo2=bar2&baz2=foo2'] 
2

Программа Perl ниже

#! /usr/bin/env perl 

use strict; 
use warnings; 

$_ = "test:?foo2=bar2&baz2=foo2test:?foo=bar&baz=footest:?foo2=bar2&baz2=foo2"; 

while (/(test:\? .*?) (?= test:\? | $)/gx) { 
    print "[$1]\n"; 
} 

производит желаемый выход из вашего вопроса, а также кронштейны для выразительности.

[test:?foo2=bar2&baz2=foo2] 
[test:?foo=bar&baz=foo] 
[test:?foo2=bar2&baz2=foo2]

Помните, что regex quantifiers are greedy и хотят сожрать столько, сколько они могут, не нарушая матч. Каждый подсегмент должен заканчиваться как можно скорее, что означает .*? семантика.

Каждый подотрезок заканчивается либо другой test:? или с истекшим строки, которую мы ищем с (?=...) нулевой шириной опережающего просмотра, обернутой вокруг | альтернативы.

Образец в приведенном выше коде использует Perl’s /x regex switch для удобства чтения. В зависимости от языка и библиотек, которые вы используете ’, вам может потребоваться удалить лишние пробелы.

+0

Я использовал ваш sytnax в тесте регулярных выражений, но матч все равно дал мне строку, содержащую два теста :? строки. Я использую Java, поэтому я предполагаю, что это может быть связано с синтаксисом? (Я удалил пробелы для тестирования). Спасибо за вашу помощь, хотя я узнал намного больше. – james

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

  • Нет связанных вопросов^_^