1

したがって、次のリンク構造をphpのpreg_match_allと一致させたいと思います。

<a garbage href="http://this.is.a.link.com/?query=this has invalid spaces" possible garbage>
<a garbage href='http://this.is.a.link.com/?query=this also has has invalid spaces' possible garbage>
<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters possible garbage>
<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters>

"と'deilmitedurlsを1つ取得できます

'#<a[^>]*?href=("|\')(.*?)("|\')#is'

または、3つすべてを取得できますが、最初の2つに次のスペースがある場合は取得できません。

'#<a[^>]*?href=("|\')?(.*?)[\s\"\'>]#is'

潜在的なスペースで区切られた「」と「」だけでなく、区切り文字なしで適切にエンコードされたURLも取得するように、これをどのように定式化できますか。

4

5 に答える 5

1

編集:私はこれを編集して、最初に投稿したものよりも少しうまく機能するようにしました。

あなたはほとんどそれを2番目の正規表現に持っています:

'#<a[^>]*?href=("|\')?(.*?)[\\1|>]#is'

次の配列を返します。

array(3) {
  [0]=>
  array(4) {
    [0]=>
    string(92) "<a garbage href="http://this.is.a.link.com/?query=this has invalid spaces" possible garbage>"
    [1]=>
    string(101) "<a garbage href='http://this.is.a.link.com/?query=this also has has invalid spaces' possible garbage>"
    [2]=>
    string(94) "<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters possible garbage>"
    [3]=>
    string(77) "<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters>"
  }
  [1]=>
  array(4) {
    [0]=>
    string(1) """
    [1]=>
    string(1) "'"
    [2]=>
    string(0) ""
    [3]=>
    string(0) ""
  }
  [2]=>
  array(4) {
    [0]=>
    string(74) "http://this.is.a.link.com/?query=this has invalid spaces" possible garbage"
    [1]=>
    string(83) "http://this.is.a.link.com/?query=this also has has invalid spaces' possible garbage"
    [2]=>
    string(77) "http://this.is.a.link.com/?query=no_spaces_but_no_delimiters possible garbage"
    [3]=>
    string(60) "http://this.is.a.link.com/?query=no_spaces_but_no_delimiters"
  }
}

区切り文字の有無にかかわらず機能します。

于 2010-11-06T02:55:21.903 に答える
1

DOM パーサーを使用します。(x)HTML を正規表現で解析することはできません。

$html = <<<END
<a garbage href="http://this.is.a.link.com/?query=this has invalid spaces" possible garbage>
<a garbage href='http://this.is.a.link.com/?query=this also has has invalid spaces' possible garbage>
<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters possible garbage>
<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters>
END;

$domd = new DOMDocument();
libxml_use_internal_errors(true);
$domd->loadHTML($html);
libxml_use_internal_errors(false);

$items = $domd->getElementsByTagName("a");
foreach ($items as $item) {
  var_dump($item->getAttribute("href"));
}
于 2010-11-06T07:34:06.197 に答える
1

OK、これはうまくいくようです:

'#<a[^>]*?href=((["\'][^\'"]+["\'])|([^"\'\s>]+))#is'

($matches[1] には URL が含まれます)

唯一の煩わしさは、引用された URL にまだ引用符が付いていることです。そのため、引用符を取り除く必要があります。

$first = substr($match, 0, 1);
if($first == '"' || $first == "'")
    $match = substr($match, 1, -1);
于 2010-11-06T02:50:05.983 に答える
0

それらを一致させたいと言うとき、リンクから情報を抽出しようとしていますか、それとも単にhrefでハイパーリンクを見つけようとしていますか?後者のみを使用している場合、これは問題なく機能するはずです。

/<a[^>]*href=[^\s].*?>/
于 2010-11-06T02:56:48.037 に答える
0

@JasonWoof が示したように、埋め込まれたオルタネーションを使用する必要があります。@DanHorriganが行ったように、キャプチャグループを使用して、使用されている引用の種類を判断することもお勧めします。否定先読み ( (?!\\2)) と所有量指定子 ( *+) を追加することで、非常に高速な非常に堅牢な正規表現を作成できます。

~
<a\\s+[^>]*?\\bhref=
(
  (["'])          # capture the opening quote
  (?:(?!\\2).)*+  # anything else, zero or more times
  \\2             # match the closing quote
|
  [^\\s>]*+   # anything but whitespace or closing brackets
)
~ix

ideone での動作をご覧ください。 (バックスラッシュが 2 つ付いているのは、正規表現が PHP ヒアドキュメントの形式で記述されているためです。私は nowdoc を使用したいと考えていますが、ideone はまだ PHP 5.2 を実行しているようです。)

于 2010-11-06T09:45:27.727 に答える