Мне нужно регулярное выражение, чтобы найти URL, который не находится внутри любого тега HTML или значение атрибута любого тега HTML

У меня есть содержание HTML в следующем тексте.

    "This is my text to be parsed which contains url 
    http://someurl.com?param1=foo&params2=bar 
 <a href="http://thisshouldnotbetampered.com">
    some text and a url http://someotherurl.com test 1q2w
 </a> <img src="http://someasseturl.com/abc.jpeg"/>
    <span>i have a link too http://someurlinsidespan.com?xyz=abc </span> 
    "

Требуется регулярное выражение, которое преобразует простые URL-адреса в гиперссылки (без изменения существующих гиперссылок)

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

    "This is my text to be parsed which contains url 
    <a href="http://someurl.com?param1=foo&params2=bar">
http://someurl.com?param1=foo&params2=bar</a> 
 <a href="http://thisshouldnotbetampered.com">
    some text and a url http://someotherurl.com test 
1q2w </a> <img src="http://someasseturl.com/abc.jpeg"/>
    <span>i have a link too <a href="http://someurlinsidespan.com?xyz=abc">http://someurlinsidespan.com?xyz=abc</a> </span> "

4 ответа

Отказ от ответственности: Вы не должны использовать регулярные выражения для этой задачи, используйте анализатор HTML. Это POC, чтобы продемонстрировать, что это возможно, если вы ожидаете хорошего форматированного HTML (которого у вас все равно не будет).

Итак, вот что я придумала:
(https?:\/\/(?:w{1,3}.)?[^\s]*?(?:\.[a-z]+)+)(?![^<]*?(?:<\/\w+>|\/?>))

Что это значит?

  • (: группа 1
  • https?: матч http или же https
  • \/\/: матч //
  • (?:w{1,3}.)?: соответствовать опционально w., ww. или же www.
  • [^\s]*?: сопоставлять что угодно, кроме пробелов ноль или более раз
  • (?:\.[a-z]+)+): сопоставить точку с последующим [a-z] символ (ы), повторите это один или несколько раз
  • (?!: негативный взгляд
    • [^<]*?: соответствовать чему-либо, кроме < ноль или более раз
    • (?:<\/\w+>|\/?>): сопоставить закрывающий тег или /> или же >
    • ): конец предвкушения
  • ): конец группы 1


regex101 online demo rubular online demo

Может быть, вы могли бы сначала выполнить поиск и замену, чтобы удалить элементы HTML. Я не знаю, Ruby, но регулярное выражение будет что-то вроде /<(\w+).*?>.*?</\1>/, Но это может быть сложно, если у вас есть вложенные элементы одного типа.

Я бы сделал что-то вроде этого:

require 'nokogiri'

doc = Nokogiri::HTML.fragment <<EOF
This is my text to be parsed which contains url 
http://someurl.com  <a href="http://thisshouldnotbetampered.com">
some text and a url http://someotherurl.com test 1q2w </a> <img src="http://someasseturl.com/abc.jpeg"/>
EOF

doc.search('*').each{|n| n.replace "\n"}

URI.extract doc.text
#=> ["http://someurl.com"]

Может быть, попробуйте http://rubular.com/.. Есть некоторые Regex Советы помогут вам получить желаемый результат.

Другие вопросы по тегам