Javascript regex для извлечения текста привязки и URL из привязанных тегов
У меня есть абзац текста в переменной javascript под названием "input_content", и этот текст содержит несколько тегов/ссылок привязки. Я хотел бы сопоставить все теги привязки и извлечь текст привязки и URL-адрес и поместить его в массив, подобный (или похожий):
Array
(
[0] => Array
(
[0] => <a href="#" onclick="location.href='http://yahoo.com'; return false;">Yahoo</a>
[1] => http://yahoo.com
[2] => Yahoo
)
[1] => Array
(
[0] => <a href="#" onclick="location.href='http://google.com'; return false;">Google</a>
[1] => http://google.com
[2] => Google
)
)
Я взломал его ( http://pastie.org/339755), но я преувеличиваю этот момент. Спасибо за помощь!
Ответы
Ответ 1
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]:
- arguments [1] - это весь якорь
- arguments [2] - это часть href
- arguments [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
Ответ 2
Так как вы предположительно запускаете javascript в веб-браузере, regex кажется для этого плохой идеей. Если абзац пришел со страницы в первую очередь, получите дескриптор контейнера, вызовите .getElementsByTagName()
, чтобы получить привязки, а затем извлеките значения, которые вы хотите таким образом.
Если это невозможно, создайте новый элемент элемента html, присвойте ему свой текст свойству .innerHTML, а затем вызовите .getElementsByTagName()
.
Ответ 3
Я думаю, что у Джоэла есть право на это - регулярные выражения, как известно, плохо играют с разметкой, так как слишком много возможностей для рассмотрения. Существуют ли другие атрибуты привязанных тегов? В каком порядке они? Является ли разделяющим пробелом всегда одно пространство? Увидев, что у вас уже есть браузер 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(), если хотите сохранить разметку.
Ответ 4
Я думаю, JQuery будет вашим лучшим выбором. Это не лучший script, и я уверен, что другие могут дать что-то лучшее. Но это создает массив именно того, что вы ищете.
<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>
Ответ 5
В интересах поисковиков: я создал что-то, что будет работать с дополнительными атрибутами в теге привязки. Для тех, кто не знаком с 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 и regex101.
В качестве альтернативы вы можете получить информацию из таких групп:
var returnText = text.replace(urlPattern, function(fullText, beforeLink, anchorContent, href, lnkUrl, linkText, endAnchor){
return "The bits you want e.g. linkText";
});
Ответ 6
Чтобы извлечь URL-адрес:
var pattern =/.href= "(.)".*/;
var url = string.replace(pattern, '$ 1');
Демо:
//var string = '<a id="btn" target="_blank" class="button" href="#" onclick="location.href='https://yourdomainame.com:4089?param=751&2ndparam=2345'; return false;">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