У меня есть любой тип текстовых записей:
#teste #teste: ##teste oi esse é um tempo com #blalbalb no meio da #gxD https://g1.globo.com/economia/noticia/2019/09/16/precos-do-#petroleo-disparam-apos-ataques-a-instalacoes-na-arabia-saudita.ghtml http://nexus.dfdff.com/-#browse:central http://nexus.ssdff.com/#browse/browse:npm-group https://mail.google.com/mail/u/0/#inbox
Мне нужно идентифицировать только те тексты, которые содержат #.Сложность состоит в том, что URL-адреса могут также содержать #.
#
Мое регулярное выражение до сих пор: https://regex101.com/r/LLHo0w/3
\B(\#[a-zA-Z]+\b)(?!\/|\-|\:)
Неправильное совпадение: https://mail.google.com/mail/u/0/#inbox немного текста # привет
Правильное совпадение: https://mail.google.com/mail/u/0/#inbox немного текста # привет
\B(\#[a-zA-Z]+\b)(?!\/|\-|\:) var html = "<a href="#" data-timeline-action="search">$1</a>" var text= "vamos ser #amigos pode ser? https://mail.google.com/mail/u/0/#inbox" text.replace(/\B(\#[a-zA-Z]+\b)(?!\/|\-|\:)/ig, html);
Я попробовал это и похоже, что оно работает:
/(?:^|\s)(#[a-z\d-_]+)/ig
Для извлечения хэш-тегов использование пробелов в качестве разделителя выглядит гораздо менее хрупким, чем черный список символов URL:
/(?<=#|\s|^)(#[^\s#]+)/g
При этом используется положительный взгляд за задним числом для проверки пробела или начала строки перед литералом # (не обращая внимания на несколько # с), затем сожрать непробельные символы без хэштега для захвата самого тега.
const text = `#teste #teste: ##teste oi esse é um tempo com #blalbalb no meio da #gxD https://g1.globo.com/economia/noticia/2019/09/16/precos-do-#petroleo-disparam-apos-ataques-a-instalacoes-na-arabia-saudita.ghtml http://nexus.dfdff.com/-#browse:central http://nexus.ssdff.com/#browse/browse:npm-group https://mail.google.com/mail/u/0/#inbox`; const pattern = /(?<=#|\s|^)(#[^\s#]+)/g; console.log(text.match(pattern)); console.log(text.replace(pattern, "<REPLACED: '$1'>")); console.log( "vamos ser #amigos pode ser? https://mail.google.com/mail/u/0/#inbox".replace( pattern, '<a href="#" data-timeline-action="search">$1</a>' ) );
Если ваш браузер не поддерживает lookbehinds , вы можете использовать дополнительную группу захвата, чтобы гарантировать, что замена сохраняет префикс:
/(\s#+|\s|^)(#[^\s#]+)/g
const text = `#teste #teste: ##teste oi esse é um tempo com #blalbalb no meio da #gxD https://g1.globo.com/economia/noticia/2019/09/16/precos-do-#petroleo-disparam-apos-ataques-a-instalacoes-na-arabia-saudita.ghtml http://nexus.dfdff.com/-#browse:central http://nexus.ssdff.com/#browse/browse:npm-group https://mail.google.com/mail/u/0/#inbox`; const pattern = /(\s#+|\s|^)(#[^\s#]+)/g; for (let m; m = pattern.exec(text); console.log(m)); console.log("---"); console.log(text.replace(pattern, "$1<REPLACED: '$2'>")); console.log( "vamos ser #amigos pode ser? https://mail.google.com/mail/u/0/#inbox".replace( pattern, '$1<a href="#" data-timeline-action="search">$2</a>' ) );
Другой вариант - сопоставить все URL-адреса и захватить хэштеги в группе захвата.
https?:\/\/\S+|(?:^|\s+)(#[a-zA-Z]+)
По частям
https?:\/\/
s
://
\S+
|
(?:^|\s+)
(#[a-zA-Z]+)
(используйте \S+ вместо [a-zA-Z]+ для сопоставления без пробельных символов)
[a-zA-Z]+
Regex demo
const regex = /https?:\/\/\S+|(?:^|\s+)(#[a-zA-Z]+)/g; const str = `#teste #teste: ##teste oi esse é um tempo com #blalbalb no meio da #gxD https://g1.globo.com/economia/noticia/2019/09/16/precos-do-#petroleo-disparam-apos-ataques-a-instalacoes-na-arabia-saudita.ghtml http://nexus.dfdff.com/-#browse:central http://nexus.ssdff.com/#browse/browse:npm-group https://mail.google.com/mail/u/0/#inbox`; let m; while ((m = regex.exec(str)) !== null) { // This is necessary to avoid infinite loops with zero-width matches if (m.index === regex.lastIndex) { regex.lastIndex++; } if (undefined !== m[1]) { console.log(m[1]); } }