2

私はパターンの配列を持っています:

$patterns= array(
    '#http://(www\.)?domain-1.com/.*#i',
    '#http://(www\.)?domain-2.com/.*#i',
    ...
);

複数のテキストとURLを含む長い文字列があり、文字列で最初に発生したURLに一致させたいのですが、これだけを試しました:

foreach ($patterns as $pattern) {
    preg_match($pattern, $the_string, $match);
    echo '<pre>'; print_r($match); echo '</pre>';
}

URL を含む一部のパターンと配列に一致しない空の配列を返しますが、配列の順序によっては$patterns

最初に発生したこれらのパターンの一致をどのように見つけることができますか?

4

3 に答える 3

5

基本的に次の 3 つのオプションがあります。

  1. 一般的な URL パターンを照合し、取得したパターンに対してその URL を実行します。一致するものがない場合は、一般的なパターンの 2 番目の結果に進みます。
  2. フラグを使用してすべてのパターンを実行しPREG_OFFSET_CAPTURE、パターンが一致したオフセットを取得します。最も低いオフセットを見つけて、結果を返します
  3. さまざまなパターンを組み合わせて 1 つのパターンにします。パターンの長さには制限があることに注意してください (コンパイルされた形式で 64K ) 。

オプション 2:

<?php

$text = "hello world http://www.domain-2.com/foo comes before http://www.domain-1.com/bar";
$patterns= array(
    '#http://(www\.)?domain-1.com/[^\s]*#i',
    '#http://(www\.)?domain-2.com/[^\s]*#i',
);

$match = null;
$offset = null;
foreach ($patterns as $pattern) {
    if (preg_match($pattern, $text, $matches, PREG_OFFSET_CAPTURE)) {
        if ($matches[0][1] < $offset || $offset === null) {
            $offset = $matches[0][1];
            $match = $matches[0][0];
        }
    }
}

var_dump($match);

デモ パターンを変更したことに注意してください。パターンが想定以上に一致するのを防ぐために、.*(なんでも) を(スペース以外のすべて)に置き換えました。[^\s]*

于 2012-06-26T13:08:05.120 に答える
2

私はあなたがこれを探していると思います:

foreach ($patterns as $pattern) {
    if (preg_match($pattern, $the_string, $match)) {
        echo '<pre>'; print_r($match); echo '</pre>';
        break;
    }
}

アップデート:

次に、これをリンクするオフセットを使用する必要があると思います:

$matches = array();
foreach ($patterns as $pattern) {
    if (preg_match($pattern, $the_string, $match, PREG_OFFSET_CAPTURE)) {
        $matches[$match[0][1]] = $match[0][0];
    }
}
echo reset($matches);
于 2012-06-26T12:50:35.180 に答える
1

すべての文字列を一度に 1 つずつ評価し、最も早いものを取得する以外に方法は考えられません。

$easliestPos = strlen($the_string) + 1;
$earliestMatch = false;

foreach ($patterns as $pattern) { 
    if (preg_match($pattern, $the_string, $match)) { 
        $myMatch = $match[0];
        $myMatchPos = strpos($myMatch, $the_string);
        if ($myMatchPos < $easliestPos ) {
            $easliestPos = $myMatchPos;
            $earliestMatch = $myMatch ;
        }
    }
 }

 if ($earliestMatch ) {
    echo $earliestMatch;
 }
于 2012-06-26T13:13:47.103 に答える