RegEx Advanced: Позитивный взгляд позади - PullRequest
5 голосов
/ 21 апреля 2010

Это моя тестовая строка:

<img rel="{objectid:498,newobject:1,fileid:338}" width="80" height="60" align="left" src="../../../../files/jpg1/Desert1.jpg" alt="" />

Я хочу получить каждый элемент JSON, сформированный между атрибутом rel. Это работает для первого элемента (objectid).

Вот мой ReqEx, который отлично работает:

(?<=(rel="\{objectid:))\d+(?=[,|\}])

Но я хочу сделать что-то подобное, что не работает:

(?<=(rel="\{.*objectid:))\d+(?=[,|\}])

Так что я могу проанализировать каждый элемент строки поиска.

Я использую Java-ReqEx

Ответы [ 3 ]

2 голосов
/ 21 апреля 2010

Java (и почти все разновидности регулярных выражений, кроме .NET и JGSoft) не поддерживают бесконечное повторение внутри виджетов.

Вместо этого вы можете использовать группы захвата. Кроме того, лучше использовать [^{]* вместо .* и обеспечить границы слов с помощью \b.

rel="\{[^{]*\bobjectid:(\d+)

должно быть достаточно (затем посмотрите на группу захвата 1 для значения атрибута.

1 голос
/ 21 апреля 2010

Хотите перебрать все пары ключ / значение? Для этого вам не нужно смотреть назад:

String s = 
    "<img rel=\"{objectid:498,newobject:1,fileid:338}\" " +
    "width=\"80\" height=\"60\" align=\"left\" " +
    "src=\"../../../../files/jpg1/Desert1.jpg\" alt=\"\" />";
Pattern p = Pattern.compile(
    "(?:\\brel=\"\\{|\\G,)(\\w+):(\\w+)");
Matcher m = p.matcher(s);
while (m.find())
{
  System.out.printf("%s = %s%n", m.group(1), m.group(2));
}

При первом вызове find() первая часть регулярного выражения совпадает с rel="{. При последующих вызовах вторая альтернатива (\G,) вступает во владение, чтобы соответствовать запятой, но только если она сразу следует за предыдущим соответствием. В любом случае это оставляет вас в очереди на (\w+):(\w+), чтобы соответствовать следующей паре ключ / значение, и никогда не может совпадать где-либо за пределами атрибута rel.

Я предполагаю, что вы применяете регулярное выражение к изолированному тегу IMG, как вы его опубликовали, а не ко всему HTML-файлу. Кроме того, регулярное выражение может потребоваться небольшая настройка, чтобы соответствовать вашим фактическим данным. Например, вам может потребоваться более общий ([^:]+):([^,}]+) вместо (\w+):(\w+).

0 голосов
/ 21 апреля 2010

Lookaheads и lookbehind могут вообще не содержать произвольных регулярных выражений: большинство движков (включая Java) требуют, чтобы их длина была общеизвестна, поэтому вы не можете использовать в них квантификаторы типа *.

Почему вы все-таки используете здесь взгляды и взгляды? Просто используйте вместо этого группы захвата, это намного проще.

rel="\{.*objectid:(\d+)

Теперь первая группа захвата будет содержать идентификатор.

...