Regex захватывает группу - PullRequest
1 голос
/ 05 мая 2011

У меня есть это регулярное выражение

(?:\<a[^*]href="(http://[^"]+?|[^"]+?\.pdf)"+?[^>]*?)>

Смысл этого регулярного выражения в том, чтобы захватить каждый закрывающий тег ('>') якоря, у которого есть ссылка, начинающаяся с "http://" или заканчивающаяся" .pdf ".

Регулярное выражение работает, однако оно захватывает первую часть якоря, которое мне абсолютно НЕ нужно захватывать.

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

<a href="http://blabla">omg</a>
<a href="blabla">omg</a>
<a href="http://blabla.pdf">omg</a>
<a href="/blabla.pdf">omg</a>

Например: если мы возьмем первое совпадение:

<a href="http://blabla">

Я хочу взять только последнюю скобку (ту, которую я окружил скобками):

<a href="http://blabla"(>)

Так почему не захватившая группа захватывает? А как мне взять только последний кронштейн якоря

Даже если я упростил свое регулярное выражение до следующего, оно все равно не работает

(?:\<a[^*]href="http://[^"]+"+[^>]*)(>)

Спасибо,

Ответы [ 5 ]

4 голосов
/ 05 мая 2011

Перепишите ваше регулярное выражение как:

(?:\<a[^*]href="(?:http://[^"]+?|[^"]+?\.pdf)"+?[^>]*?)(>)
   non capture __^^                                    ^ ^
                                             capture __|_|

Как сказал Тони Лукасавадж, существует ненужная группа без захвата, и, кроме того, нет необходимости бежать <, поэтому она становится:

  <a[^*]href="(?:http://[^"]+?|[^"]+?\.pdf)"+?[^>]*?(>)
non capture __^^                                    ^ ^
                                          capture __|_|
3 голосов
/ 05 мая 2011

Вы объединяете два разных понятия: захват и потребление .Регулярные выражения обычно потребляют все, что им соответствует;это просто, как они работают.Кроме того, большинство разновидностей регулярных выражений позволяют вам использовать группы захвата , чтобы выделять определенные части общего соответствия.(Общее совпадение часто называют нулевой группой захвата, но это всего лишь фигура речи.)

Звучит так, как будто вы пытаетесь сопоставить целый тег <A>, но только потребляетефинал >.Это невозможно в большинстве разновидностей регулярных выражений, включая JavaScript.Но если вы используете Perl или PHP, вы можете использовать \K для подмены начальной позиции совпадения:

(?i)<a\s+[^>]+?href="http://[^"]+"[^>]*\K>

А в .NET вы можете использовать lookbehind (который, как и lookahead, совпадает безпотребления):

(?i)"(?<=<a\s+[^>]+?href="http://[^"]+"[^>]*)>

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

2 голосов
/ 05 мая 2011

Если я правильно понимаю, что вы хотите сопоставить только знак «больше» (>), который является частью закрывающего тега привязки, это должно сделать это:

\<a[^*]href="(http://[^"]+?|[^"]+?\.pdf)"+?[^>]*?(>)
1 голос
/ 05 мая 2011

Если я правильно понимаю ваш запрос ...

\<a[^*]href="(?:http://[^"]+?|[^"]+?\.pdf)"+?[^>]*?(>)
0 голосов
/ 05 мая 2011

Ваши круглые скобки находятся вокруг самого тега и содержимого href, так что это то, что будет захвачено.Если вам нужно зафиксировать закрывающий символ>, поместите вокруг него круглые скобки.

...