web-dev-qa-db-ja.com

アンカータグからアンカーテキストとURLを抽出するjavascript正規表現

'input_content'というJavaScript変数にテキストの段落があり、そのテキストには複数のアンカータグ/リンクが含まれています。すべてのアンカータグを照合し、アンカーテキストとURLを抽出して、次のような(または類似の)配列に配置したいと思います。

アレイ
(
 [0] =>アレイ
(
 [0] => <a href="http://yahoo.com"> Yahoo < /a>
[1] => http://yahoo.com 
 [2] => Yahoo 
)
 [1] =>アレイ
(
 [0] => <a href="http://google.com"> Google </a> 
 [1] => http://google.com 
 [2] => Google 
)
)

私はそれにひびを入れました( http://pastie.org/339755 )、しかし私はこの点を超えて困惑しています。助けてくれてありがとう!

15
var matches = [];

input_content.replace(/[^<]*(<a href="([^"]+)">([^<]+)<\/a>)/g, function () {
    matches.Push(Array.prototype.slice.call(arguments, 1, 4))
});

これは、アンカーが常に<a href="...">...</a>の形式であると想定しています。つまり、他の属性(たとえば、target)がある場合は機能しません。これに対応するために正規表現を改善できます。

正規表現を分解するには:

 /->正規表現を開始する
 [^ <] *->最初の<
まですべての文字をスキップする(->最初のトークンのキャプチャを開始する
 <a href = "->アンカーの最初のビットをキャプチャします
(-> 2番目のトークンのキャプチャを開始します
 [^"] +-> "
まですべての文字をキャプチャします)-> 2番目のキャプチャを終了しますtoken 
 ">->より多くのアンカーをキャプチャします
(-> 3番目のトークンのキャプチャを開始します
 [^ <] +-> <
まですべての文字をキャプチャします)-> 3番目のトークンのキャプチャを終了します
 <\/a>->アンカーの最後のビットをキャプチャします
)->最初のトークンのキャプチャを終了します
/g->正規表現を終了し、追加します文字列内のすべてのアンカーに一致するグローバルフラグ

無名関数を呼び出すたびに、2番目、3番目、4番目の引数として3つのトークン、つまり引数[1]、引数[2]、引数[3]を受け取ります。

  • 引数[1]はアンカー全体です
  • 引数[2]はhrefの部分です
  • 引数[3]は内部のテキストです

ハックを使用して、これら3つの引数を新しい配列としてメインのmatches配列にプッシュします。 arguments組み込み変数は真のJavaScript配列ではないため、必要なアイテムを抽出するには、それにsplit配列メソッドを適用する必要があります。

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 
47
Ates Goral

おそらくWebブラウザでJavaScriptを実行しているので、正規表現はこれには悪い考えのようです。段落が最初にページからのものである場合は、コンテナのハンドルを取得し、.getElementsByTagName()を呼び出してアンカーを取得してから、必要な値をその方法で抽出します。

それが不可能な場合は、新しいhtml要素オブジェクトを作成し、テキストをその.innerHTMLプロパティに割り当ててから、.getElementsByTagName()を呼び出します。

10
Joel Coehoorn

Joelにはその権利があると思います。考慮すべき可能性が多すぎるため、正規表現はマークアップでうまく機能しないことで有名です。アンカータグに他の属性はありますか?彼らはどのような順序ですか?分離する空白は常に単一のスペースですか?すでにブラウザのHTML parserが利用可能であるため、代わりにそれを機能させるのが最善です。

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;
}

これにより、リンクの格納方法に関係なく、説明したような配列が返されます。パラメータ名を「container」に変更し、最初の2行を削除することで、テキストではなく渡された要素を処理するように関数を変更できることに注意してください。 textContent/innerTextプロパティは、リンクに表示されるテキストを取得し、マークアップ(太字/斜体/フォント/…)を取り除きます。マークアップを保持したい場合は、.textContentを.innerHTMLに置き換え、内部のif()ステートメントを削除できます。

7
Ben Blank

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>
2
Brig Lamoreaux

検索者のために:アンカータグの追加の属性で機能するものを作成しました。正規表現に精通していない人にとって、ドル($ 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";
                });
1
HockeyJ

URLを抽出するには:

var pattern = /.href="(.)".*/; var url = string.replace(pattern、 '$ 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

1
JohnP2