Регулярное выражение Javascript для извлечения текста привязки и URL-адреса из тегов привязки
-
21-08-2019 - |
Вопрос
У меня есть абзац текста в переменной javascript под названием «input_content», и этот текст содержит несколько тегов/ссылок привязки.Я хотел бы сопоставить все теги привязки, извлечь текст привязки и URL-адрес и поместить их в массив, подобный (или похожий) на этот:
Array ( [0] => Array ( [0] => <a href="http://yahoo.com">Yahoo</a> [1] => http://yahoo.com [2] => Yahoo ) [1] => Array ( [0] => <a href="http://google.com">Google</a> [1] => http://google.com [2] => Google ) )
Я это попробовал (http://pastie.org/339755), но я в тупике.Спасибо за помощь!
Решение
var matches = [];
input_content.replace(/[^<]*(<a href="([^"]+)">([^<]+)<\/a>)/g, function () {
matches.push(Array.prototype.slice.call(arguments, 1, 4))
});
Это предполагает, что ваши якоря всегда будут в форме <a href="...">...</a>
то естьэто не будет работать, если есть какие-либо другие атрибуты (например, target
).Регулярное выражение можно улучшить, чтобы учесть это.
Чтобы разбить регулярное выражение:
/ -> start regular expression [^<]* -> skip all characters until the first < ( -> start capturing first token <a href=" -> capture first bit of anchor ( -> start capturing second token [^"]+ -> capture all characters until a " ) -> end capturing second token "> -> capture more of the anchor ( -> start capturing third token [^<]+ -> capture all characters until a < ) -> end capturing third token <\/a> -> capture last bit of anchor ) -> end capturing first token /g -> end regular expression, add global flag to match all anchors in string
Каждый вызов нашей анонимной функции будет получать три токена в качестве второго, третьего и четвертого аргументов, а именно: аргументы[1], аргументы[2], аргументы[3]:
- аргументы[1] — это весь якорь
- аргументы[2] — это часть href
- аргументы[3] — это текст внутри
Мы воспользуемся хаком, чтобы поместить эти три аргумента в виде нового массива в наш основной массив. matches
множество.А arguments
встроенная переменная не является настоящим массивом JavaScript, поэтому нам придется применить split
Метод Array для извлечения нужных нам элементов:
Array.prototype.slice.call(arguments, 1, 4)
Это позволит извлечь элементы из arguments
начиная с индекса 1 и заканчивая (не включительно) индексом 4.
var input_content = "blah \
<a href=\"http://yahoo.com\">Yahoo</a> \
blah \
<a href=\"http://google.com\">Google</a> \
blah";
var matches = [];
input_content.replace(/[^<]*(<a href="([^"]+)">([^<]+)<\/a>)/g, function () {
matches.push(Array.prototype.slice.call(arguments, 1, 4));
});
alert(matches.join("\n"));
Дает:
<a href="http://yahoo.com">Yahoo</a>,http://yahoo.com,Yahoo <a href="http://google.com">Google</a>,http://google.com,Google
Другие советы
Поскольку вы предположительно запускаете JavaScript в веб-браузере, регулярное выражение кажется плохой идеей для этого.Если абзац изначально пришел со страницы, получите дескриптор контейнера, вызовите .getElementsByTagName()
чтобы получить привязки, а затем таким образом извлечь нужные значения.
Если это невозможно, создайте новый объект элемента html, назначьте свой текст его свойству .innerHTML, а затем вызовите .getElementsByTagName()
.
Я думаю, что Джоэл прав: регулярные выражения печально известны своей плохой работой с разметкой, поскольку существует слишком много возможностей, которые нужно учитывать.Существуют ли другие атрибуты тегов привязки?В каком порядке они находятся?Всегда ли разделительный пробел представляет собой один пробел?Поскольку у вас уже есть HTML-код браузера парсер доступно, лучше всего использовать это вместо этого.
function getLinks(html) {
var container = document.createElement("p");
container.innerHTML = html;
var anchors = container.getElementsByTagName("a");
var list = [];
for (var i = 0; i < anchors.length; i++) {
var href = anchors[i].href;
var text = anchors[i].textContent;
if (text === undefined) text = anchors[i].innerText;
list.push(['<a href="' + href + '">' + text + '</a>', href, text];
}
return list;
}
Это вернет массив, подобный тому, который вы описываете, независимо от того, как хранятся ссылки.Обратите внимание, что вы можете изменить функцию для работы с переданным элементом вместо текста, изменив имя параметра на «контейнер» и удалив первые две строки.Свойство textContent/innerText получает текст, отображаемый для ссылки, без всякой разметки (жирный/курсив/шрифт/…).Вы можете заменить .textContent на .innerHTML и удалить внутренний оператор if(), если хотите сохранить разметку.
Я думаю JQuery будет лучшим выбором.Это не лучший сценарий, и я уверен, что другие могут предложить что-то лучше.Но это создает массив именно того, что вы ищете.
<script type="text/javascript">
// From http://brandonaaron.net Thanks!
jQuery.fn.outerHTML = function() {
return $('<div>').append( this.eq(0).clone() ).html();
};
var items = new Array();
var i = 0;
$(document).ready(function(){
$("a").each(function(){
items[i] = {el:$(this).outerHTML(),href:this.href,text:this.text};
i++;
});
});
function showItems(){
alert(items);
}
</script>
Чтобы извлечь URL-адрес:
вар шаблон = /.href="(.)".*/;var url = string.replace(шаблон, '$1');
Демо:
//var string = '<a id="btn" target="_blank" class="button" href="https://yourdomainame.com:4089?param=751&2ndparam=2345">Buy Now</a>;'
//uncomment the above as an example of link.outerHTML
var string = link.outerHTML
var pattern = /.*href="(.*)".*/;
var href = string.replace(pattern,'$1');
alert(href)
Для «текста привязки» почему бы не использовать:link.innerHtml
В пользу поисковиков:Я создал что-то, что будет работать с дополнительными атрибутами в теге привязки.Для тех, кто не знаком с Regex, значения в долларах (1 доллар и т. д.) соответствуют группам регулярных выражений.
var text = 'This is my <a target="_blank" href="www.google.co.uk">link</a> Text';
var urlPattern = /([^+>]*)[^<]*(<a [^>]*(href="([^>^\"]*)")[^>]*>)([^<]+)(<\/a>)/gi;
var output = text.replace(urlPattern, "$1___$2___$3___$4___$5___$6");
alert(output);
Смотрите работу jsFiddle и регулярное выражение101.
Альтернативно, вы можете получить информацию из групп следующим образом:
var returnText = text.replace(urlPattern, function(fullText, beforeLink, anchorContent, href, lnkUrl, linkText, endAnchor){
return "The bits you want e.g. linkText";
});