Необязательная группа regex С# - должна действовать жадно?

имея регулярное выражение ~ вот так:

blablabla.+?(?:<a href="(http://.+?)" target="_blank">)?

Я хочу захватить URL-адрес, если я его найду... находит что-то, но я не получаю ссылку (захват всегда пуст). Теперь, если я удалю вопросительный знак в конце, как это

blablabla.+?(?:<a href="(http://.+?)" target="_blank">)

Это будет соответствовать только материалам, на которые есть ссылка в конце... сейчас 2:40 утра... и у меня нет идей...

--Редактировать--

образец ввода:

blablabla asd 1234t535 <a href="http://google.com" target="_blank">

ожидаемый результат:

match 0:

    group 1: <a href="http://google.com" target="_blank">
    group 2: http://google.com`

Я просто хочу "http://google.com" или ""


person argh    schedule 07.03.2011    source источник
comment
А что произойдет, если вы добавите .* в конце последнего?   -  person markijbema    schedule 07.03.2011
comment
какова цель blablabla.+?   -  person amcashcow    schedule 07.03.2011
comment
было бы хорошо, если бы вы могли предоставить пример ввода и ожидаемый результат.   -  person Fun Mun Pieng    schedule 07.03.2011
comment
@amcashcow соответствует ЧТО-НИБУДЬ, а затем ВСЁ, пока не найдёте ссылку   -  person argh    schedule 07.03.2011
comment
@markijbema нет, извините, ложная тревога   -  person argh    schedule 07.03.2011


Ответы (3)


Вы проводите матч всей струны? Если это так, попробуйте добавить .* в конец первого регулярного выражения и посмотрите, чему оно соответствует. Проблема с первым регулярным выражением заключается в том, что оно может соответствовать чему угодно после blablabla из-за .+? (что приводит к пустому захвату), но часть в скобках по-прежнему не будет соответствовать тегу a, если только он не находится в конце строки. Кстати, глядя на ваш ожидаемый результат, захват 1 будет URL-адресом; скобки вокруг всего тега HTML не захватываются из-за ?: в начале.

person Jeremiah Willcock    schedule 07.03.2011
comment
но .+? должен действовать как не жадный == останавливаться на ‹a href= - person argh; 07.03.2011
comment
@argh: Да, будет, если остальная часть строки соответствует <a href ..., но для этого требуется, чтобы вся оставшаяся часть строки была тегом. - person Jeremiah Willcock; 07.03.2011
comment
ХА! ПОНЯТНО! Спасибо, Иеремия - вы привели меня к решению: blablabla.+?‹a href=(?:(http://.+?) target=_blank›) - person argh; 07.03.2011
comment
@argh: Какая польза от перемещения этой группы в скобках? - person Jeremiah Willcock; 07.03.2011
comment
Да... ну... это сработало на секунду, но только потому, что позже была ссылка, в которой не было тега target=_blank... ах... Я был так счастлив на секунду... - person argh; 07.03.2011
comment
@argh: Попробуйте .* вещь, предложенную ранее; это должно решить проблему, если только теги не соответствуют указанному вами регулярному выражению. Кстати, у вас будет несколько ссылок во входном тексте? Как вы планируете проходить через них? - person Jeremiah Willcock; 07.03.2011
comment
Попробовал это .* - все равно не повезло... и меня устраивает 1 ссылка на страницу - для большинства страниц меня интересует только 1 ссылка, и это та, которая выходит вне сайт - person argh; 09.03.2011

вам не нужно .+? в начале регулярное выражение все равно будет искать весь ввод

у вас также есть закрывающий '>' сразу после пробела, который ограничит ваши совпадения

(?:<a href="(http://.+?)" target="_blank".*?>)

тест регулярного выражения

person amcashcow    schedule 07.03.2011
comment
ок, извините, мой образец не совсем точен... Мне нужна эта блаблабла впереди - в основном мне нужно извлечь URL-адреса других сайтов из плохо сформированного HTML... поэтому они делают что-то вроде: Название компании shitty unclosed html tags ‹a href =google.com target=_blank - person argh; 07.03.2011
comment
хорошо, вы можете поставить перед ним все, что хотите, но в этом нет необходимости, если вы не хотите ограничивать, какие URL-адреса совпадают. и если вы делаете это, будьте как можно более конкретными - person amcashcow; 07.03.2011
comment
да, и это именно то, что я хочу сделать - person argh; 09.03.2011

Это трейлинг? это вас раздражает. Причина: пометив это как необязательный, вы разрешаете .+? схватить его.

blablabla.*(?:<a href="((http://)?.*)".+target="_blank".*>)

Я немного изменил его... .+? в основном то же самое, что и .*, и если у вас может ничего не быть в вашем href (вы указали, что хотите ""), вам нужно сделать http необязательным, а также завершающий текст. Кроме того, .* перед target означает, что у вас есть хотя бы один пробел или символ, но может быть и больше (несколько пробелов или других атрибутов). .* перед > означает, что после него могут быть пробелы или другие атрибуты.

Это вообще не будет соответствовать строке, если нет <a href...>, но это то, что вы хотите, верно?

(?: ... ) можно полностью отбросить, если вам не нужно захватывать всю <a href...> часть.

Это не удастся, если атрибуты не будут перечислены в указанном порядке... что является одной из причин, по которой регулярное выражение нельзя использовать для анализа html. Но если вы уверены, что href всегда будет предшествовать цели, это должно делать то, что вам нужно.

person James King    schedule 07.03.2011
comment
Это вообще не будет соответствовать строке, если нет ‹a href...›, но это то, что вы хотите, верно? --› Нет. В таком случае нам нужно положительное совпадение с пустой группой захвата. - person Mark Jeronimus; 14.11.2018