Regex, чтобы найти экземпляры слова, которые не находятся в пути URL - PullRequest
3 голосов
/ 09 июня 2019

Я бы хотел сопоставить экземпляры слова в строке, если слово отсутствует в URL.

Примером может быть нахождение экземпляров 'hello' в следующем:

hello this is a regex problem http://geocities.com/hello/index.html?hello! Hello how are you!

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

/\bhello\b/i

Однако это возвращает все четыре экземпляра 'hello', включая два, содержащиеся в строке URL.

Я экспериментировал с негативными взглядами на 'http', но пока ничего не получалось. Есть идеи?

Ответы [ 3 ]

1 голос
/ 10 июня 2019

Вот несколько решений, основанных на Лучший трюк с регулярным выражением для 1) подсчета совпадений вне URL, 2) удаления совпадений не в URL и 3) переноса соответствует тегу вне URL:

s = "hello this is a regex problem http:"+"//geocities.com/hello/index.html?hello! Hello how are you!"
# Counting
p s.scan(/https?:\/\/\S*|(hello)/i).flatten.compact.count
## => 2
# Removing
p s.gsub(/(https?:\/\/\S*)|hello/i, '\1')
## => " this is a regex problem http://geocities.com/hello/index.html?hello!  how are you!"
# Wrapping with a tag
p s.gsub(/(https?:\/\/\S*)|(hello)/i) { $1 || "<span>#{$2}</span>" }
## => "<span>hello</span> this is a regex problem http://geocities.com/hello/index.html?hello! <span>Hello</span> how are you!"

Вы можете заключить шаблон hello в границы слов, если вам нужно соответствовать целому слову, \bhello\b.

См. онлайн Ruby демо

Примечания

  • .scan(/https?:\/\/\S*|(hello)/i).flatten.compact.count - соответствует URL-адресу, начинающемуся с http или https, или соответствует и захватывает hello в группе 1, .scan возвращает только захваченные подстроки, но также возвращает nil, как только URL-адрес соответствует, поэтому .compact требуется для удаления nil элементов из flatten ed массива, а .count возвращает количество элементов в массиве.
  • .gsub(/(https?:\/\/\S*)|hello/i, '\1') сопоставляет и записывает URL-адреса в группу 1, а hello просто сопоставляет все hello s вне URL-адресов, и совпадения заменяются на \1, обратная ссылка на группу 1 представляет собой пустую строку, когда просто hello найдено.
  • s.gsub(/(https?:\/\/\S*)|(hello)/i) { $1 || "<span>#{$2}</span>" } сопоставляет и захватывает URL-адреса в Группе 1 и hello в Группе 2. Если Группа 1 была сопоставлена, $1 возвращает это значение обратно в строку, в противном случае Группа 2 оборачивается тегами и вставляется обратно в строку.
0 голосов
/ 09 июня 2019

Здесь мы можем сначала собрать наши URL, измененные желаемыми словами в группе захвата, с выражением, похожим на:

http[^\s]+|(hello|you)

Демо

RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

Рекомендации

Четвертая птица советует:

Я бы пошел за границы слова и только hello в группе: \bhttp\S+|\b(hello)\b

0 голосов
/ 09 июня 2019

Если я прав, вам нужно получить слова после URL. Вы можете просто использовать пробел (\ s) в качестве разделителя вашей строки

"http://geocities.com/hello/index.html?hello! Hello how are you!".scan(/\s(\w+)/i)

=> [["Hello"], ["how"], ["are"], ["you"]]

или

 "http://geocities.com/hello/index.html?hello! Hello how are you!".scan(/\s(hello)/i)

=> [["Hello"]]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...