1

単語グループをリンクに置き換えたい。

単語グループは、多次元配列で定義されます。何千もの用語が置換されるため、インデックスのない軽量の多次元配列が必要です。

用語の後に括弧が続く場合、または角括弧内にある場合は、何も置き換えてはなりません。

問題: 正規表現自体は正常に機能しますが、単語グループに + ? などの正規表現構文文字が含まれていると置換が壊れます。/ ( などなので、それらをマスクする必要があります。考えられるすべてのバリエーションを試しましたが、すべてのケースで機能するとは限りません。$text または $s でそれらをマスクすることはできません。

<?php

$text = "<html><body><pre>
Replace all foo / bar / baz cases here:
Case 1: Text Foo text.
Case 2: Text 'Foo' Bar text Foo.
Case 3: Text Foobar (2) text.
Case 4: Text Bar & Baz.
Case 5: Text Bar Baz?
Case 6: Text Bar? & Baz?
Case 7: Text Bar-X.

Replace nothing here (text followed by brackets) or [inside square brackets]: 
Case 1: Text Foo (text).
Case 2: Text 'Foo' Bar (text) Foo (text).
Case 3: Text Foobar (2) (text).
Case 4: Text Bar & Baz (text).
Case 5: Text Bar Baz (text).
Case 6: Text Bar? & Baz (text).
Case 7: Text Bar-X (text).
Case 8: [Text Foo]
</pre></body></html>";

$s = array(
  array("t" => "Foo",         "u" => "http://www.foo.net"),
  array("t" => "'Foo' Bar",   "u" => "http://www.foo.net"),
  array("t" => "Foobar (2)",  "u" => "http://www.foo.net"),
  array("t" => "Bar & Baz",   "u" => "http://www.foo.net"),
  array("t" => "Bar Baz?",    "u" => "http://www.foo.net"),
  array("t" => "Bar? & Baz?", "u" => "http://www.foo.net"),
  array("t" => "Bar-X",       "u" => "http://www.foo.net")
 );

$replaced = $text;
foreach ($s as $i => $row) {
# $replaced = preg_replace('/(?='.preg_quote($row["t"]).'[^\]][^(]+$)\b'.preg_quote($row["t"]).'\b/mS',
# $replaced = preg_replace('/(?='.preg_quote($row["t"], '/').'[^\]][^(]+$)\b'.preg_quote($row["t"], '/').'\b/mS',
# $replaced = preg_replace('/(?=\Q'.$row["t"].'\E[^\]][^(]+$)\b\Q'.$row["t"].'\E\b/mS',
    $replaced = preg_replace('/(?='.$row["t"].'[^\]][^(])\b'.$row["t"].'\b/mS',
                           '<a href="'.$row["u"].'">'.$row["t"].'</a>',
                           $replaced);
 }
echo $replaced;

?>
4

2 に答える 2

1

これは、少なくとも提供されたテストケースでは機能するはずです。

$replaced = preg_replace('/([.,\s!^]+)('.preg_quote($row["t"],'/').')([.,\s!$]+)(?!\()/mS',
                           '$1<a href="'.$row["u"].'">$2</a>$3',
                           $replaced);

\b一致自体が(のように)いくつかの境界内にラップされている場合、期待どおりに機能しないFoobar (2)ため、許可される文字のリストを具体的に指定する必要があります。私はすぐにそこに置き[.,\s!^]ます、あなたはおそらくあなたの仕様(のような、?)[.,\s!$]に従っていくつかの許可された文字を追加する必要があるでしょう-_

于 2010-06-19T17:02:19.693 に答える
0

あなたが何をしようとしているのか完全にはわかりませんが、「単語グループに正規表現構文文字が含まれていると壊れる」のを見たので、これらの文字をエスケープするだけでよいと思います...つまり、それらの前に \ を置きます。

編集:

私もこれでかなり行き詰まっていますが、もし私が持っているものを見せれば、おそらくあなたを助けることができます:

<?php

$text = "<html><body><pre>
Replace all foo / bar / baz cases here:
Case 1: Text Foo text.
Case 2: Text 'Foo' Bar text Foo.
Case 3: Text Foobar (2) text.
Case 4: Text Bar & Baz.
Case 5: Text Bar Baz?
Case 6: Text Bar? & Baz?
Case 7: Text Bar-X.

Replace nothing here (text followed by brackets) or [inside square brackets]: 
Case 1: Text Foo (text).
Case 2: Text 'Foo' Bar (text) Foo (text).
Case 3: Text Foobar (2) (text).
Case 4: Text Bar & Baz (text).
Case 5: Text Bar Baz (text).
Case 6: Text Bar? & Baz (text).
Case 7: Text Bar-X (text).
Case 8: [Text Foo]
</pre></body></html>";

function convertRegexChars($string)
{
    $converted = str_replace("?","&#63;",$string);
    $converted = str_replace(".","&#46;",$converted);
    $converted = str_replace("*","&#42;",$converted);
    $converted = str_replace("+","&#43;",$converted);
    return $converted;
}

$s = array(
  array("t" => "Foo",         "u" => "http://www.foo.net"),
  array("t" => "'Foo' Bar",   "u" => "http://www.foo.net"),
  array("t" => "Foobar (2)",  "u" => "http://www.foo.net"),
  array("t" => "Bar & Baz",   "u" => "http://www.foo.net"),
  array("t" => "Bar Baz?",    "u" => "http://www.foo.net"),
  array("t" => "Bar? & Baz?", "u" => "http://www.foo.net"),
  array("t" => "Bar-X",       "u" => "http://www.foo.net")
 );

$replaced = convertRegexChars($text);
foreach ($s as $i => $row) {
    $txt = convertRegexChars($row['t']);
    $replaced = preg_replace('/(?='.$txt.'[^\]][^(])\b'.$txt.'\b/mS',
                           '<a href="'.$row["u"].'">'.$txt.'</a>',
                           $replaced);
 }
echo $replaced;

?>
于 2010-06-19T12:22:56.980 に答える