Arhn - архитектура программирования

регулярное выражение javascript для извлечения текста привязки и URL из тегов привязки

У меня есть абзац текста в переменной 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), но дальше этого я в тупике. Спасибо за помощь!

15.12.2008

  • немного более надежный (возможно) regex101 (PHP), _ 2_ 28.05.2016

Ответы:


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

Каждый вызов нашей анонимной функции будет получать три токена в качестве второго, третьего и четвертого аргументов, а именно arguments [1], arguments [2], arguments [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
15.12.2008
  • Не обязательно соглашаться с тем, что регулярное выражение лучше всего подходит для этого, но проголосуйте за то, что нашли время, чтобы опубликовать хорошее объяснение и что делать, когда у вас есть совпадения. 15.12.2008
  • Большое спасибо за то, что предоставили все подробности о регулярном выражении. Очень помогает понять, как () работает для захвата токенов. 16.12.2008
  • Я согласен, что регулярное выражение, вероятно, является излишним для этого. Оглядываясь назад, я мог бы настроить цикл для использования while (tokens = regex.exec(patt)) вместо replace хака. 03.02.2010
  • +1 за полное объяснение вашего регулярного выражения. я бы немного меньше ненавидел регулярные выражения, если бы больше людей комментировали свой код вот так. 08.10.2012
  • +1 Спасибо! Я добавил исключение для других атрибутов, включая target =, немного изменив ваше регулярное выражение на основе вашего подробного объяснения того, как оно работает :-) / [^ ‹] * (‹ a href = ([^] +)? [^ ›] * ([^ ‹] +)‹ \ / A ›) / g где? [^›] * Выполняет задание 11.09.2019

  • 2

    Поскольку вы предположительно запускаете javascript в веб-браузере, регулярное выражение кажется плохой идеей для этого. Если абзац изначально был получен со страницы, получите дескриптор контейнера, вызовите .getElementsByTagName(), чтобы получить якоря, а затем извлеките нужные значения таким образом.

    Если это невозможно, создайте новый объект элемента html, назначьте свой текст его свойству .innerHTML, а затем вызовите .getElementsByTagName().

    15.12.2008

    3

    Я думаю, что Джоэл имеет на это право - регулярные выражения печально известны тем, что плохо работают с разметкой, поскольку существует слишком много возможностей для рассмотрения. Есть ли у тегов привязки другие атрибуты? В каком порядке они расположены? Всегда ли разделительный пробел представляет собой единый пробел? Поскольку у вас уже есть доступный синтаксический анализатор браузера, лучше всего использовать его вместо этого.

    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 (), если хотите сохранить разметку.

    15.12.2008

    4

    Я думаю, что лучше всего вам подойдет 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>
    
    15.12.2008
  • Спасибо. Поскольку я использую jQuery, мне кажется, что это лучше всего подходит для моих целей. Однако в нотации JSON el: el возвращает URL-адрес, а не разметку тега привязки. Есть идеи, почему? 16.12.2008
  • el должен быть фактическим элементом документа. Я искал, как получить свойство outerHtml, но нигде его не увидел. Но с элементом el вы можете добавить его обратно в DOM, если хотите. 16.12.2008
  • Догадаться!!! brandonaaron.net имеет надстройку externalHTML (). Включите это и обновите одну строку и whala !. jQuery.fn.outerHTML = function () {return $ ('‹div›') .append (this.eq (0) .clone ()) .html (); }; items [i] = {el: $ (this) .outerHTML (), href: this.href, text: this.text}; 16.12.2008
  • Обновил свой ответ. Не знал, что смогу это сделать. :) 16.12.2008

  • 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";
                    });
    
    14.07.2016

    6

    Чтобы извлечь URL:

    var pattern = /. href = "(.)". * /; var url = string.replace (шаблон, '$ 1');

    Демо:

    //var string = '<a id="btn" target="_blank" class="button" href="https://yourdomainame.com:4089?param=751&amp;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

    10.09.2016
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..