Регулярное выражение Perl для пропуска, если значение href якоря начинается с «#»

#regex #perl

Вопрос:

Я анализирую URL-адреса из строки с помощью регулярного выражения и хочу пропустить, если значение привязки href начинается с «#».

Из строки ниже я хочу пропустить это, чтобы отобразить как есть « <a href="#C4">https://www.google.com</a> »

 my $text = qq~ <a href="#C4">https://www.google.com</a>
    
    <a href="">https://www.google.com</a>
    
    content1 <video> https://google.com/ </video>my content2<video>https://google.com/</video>~;
 

Я использую это регулярное выражение для этого, но не получаю желаемый результат:

 $text =~ s/(^|s|>|()(?:<a(?:[^>]*)>)?((https|ftp)://)([^rn<>]*)(?:</a>)?/$1<a href="$2$4">$2$4</a>/gi;
 

Приведенное выше регулярное выражение возвращает результат :

 <a href="https://www.google.com">https://www.google.com</a>

<a href="https://www.google.com">https://www.google.com</a>

content1 <video> <a href="https://google.com">https://google.com</a> </video>my content2<video><a href="https://google.com">https://google.com</a></video>
 

это не пропуск первого якоря, как у «#» при запуске в href. Пожалуйста, помогите.

Комментарии:

1. Очевидным ответом было бы «Почему бы вам не использовать синтаксический анализатор HTML»?

Ответ №1:

Я смог заставить это работать с помощью (*SKIP)(*FAIL) : когда href="# внутри <a есть совпадение , оно терпит неудачу и не возвращается. Подробности см. в разделе perlre.

 $text =~ s{(^|s|>|()
           (?:<a[^>] href=['"]?#.*?</a>(*SKIP)(*FAIL)
             |<a[^>]*>|)      # If there wasn't href="#, work the old way.
           ((?:https|ftp)://) #2
           ([^rn<>]*)       #3
           (?:</a>)?
          }{$1<a href="$2$3">$2$3</a>}xgi;
 

Я также использовал s{}{} , чтобы избежать косой черты, /x сделать ее более читабельной и включить комментарии.