4

私の正規表現は以下の通りです:

(?<![\s]*?(\"|&quot;)")WORD(?![\s]*?(\"|&quot;))

ご覧のとおり、「引用符」内にない限り、WORD のすべてのインスタンスに一致させようとしています。そう...

WORD <- Find this
"WORD" <- Don't find this
"   WORD   " <- Also don't find this, even though not touching against marks
&quot;WORD&quot;  <- Dont find this (I check &quot; and " so works after htmlspecialchars)

エラーが発生しなければ、正規表現は完全に機能すると思います。

Compilation failed: lookbehind assertion is not fixed length

後読みの制限を考慮して、意図したことを行う方法はありますか?

他に考えられる方法があれば教えてください。

大変感謝します、

マシュー

ps WORD セクションには、実際には Jon Grubers の URL 検出器が含まれます。

4

2 に答える 2

3

別のアプローチをお勧めします。これは、引用符のバランスが適切である限り機能します。これは、後続の引用符の数が奇数である場合、引用符で囲まれた文字列の中にいることがわかり、後読み部分が不要になるためです。

if (preg_match(
'/WORD             # Match WORD
(?!                # unless it\'s possible to match the following here:
 (?:               # a string of characters
  (?!&quot;)       # that contains neither &quot;
  [^"]             # nor "
 )*                # (any length),
 ("|&quot;)        # followed by either " or &quot; (remember which in \1)
 (?:               # Then match
  (?:(?!\1).)*\1   # any string except our quote char(s), followed by that quote char(s)
  (?:(?!\1).)*\1   # twice,
 )*                # repeated any number of times --> even number
 (?:(?!\1).)*      # followed only by strings that don\'t contain our quote char(s)
 $                 # until the end of the string
)                  # End of lookahead/sx', 
$subject))
于 2013-06-25T15:01:06.057 に答える
1

引用符で囲まれた文字列を削除してから、残っているものを検索することをお勧めします。

$noSubs = preg_replace('/(["\']|&quot;)(\\\\\1|(?!\1).)*\1/', '', $target);
$n = preg_match_all('/\bWORD\b/', $noSubs, $matches);

上記の引用符で囲まれた文字列を置き換えるために使用した正規表現は&quote;"'を別々の文字列区切り文字として扱います。特定の区切り文字について、正規表現は次のようになります。

/"(\\"|[^"])*"/

&quot;したがって、次と同等として扱いたい場合":

/("|&quot;)(\\("|&quot;)|(?!&quot;)[^"])*("|&quot;)/i

次に、一重引用符で囲まれた文字列も処理する場合 (アポストロフィを含む単語がないことを前提としています):

/("|&quot;)(\\("|&quot;)|(?!&quot;)[^"])*("|&quot;)|'(\\'|[^'])*'/i

これらをエスケープして PHP 文字列に入れる場合は注意してください。

編集

Qtax は、一致した WORD データを置き換えようとしている可能性があると述べました。その場合、次のような正規表現を使用して文字列を簡単にトークン化できます。

/("|&quot;)(\\("|&quot;)|(?!&quot;)[^"])*("|&quot;)|((?!"|&quot;).)+/i

引用符で囲まれた文字列と引用符で囲まれていないセグメントに分けて、引用符で囲まれていないセクションのみで置換操作を行う新しい文字列を作成します。

$tokenizer = '/("|&quot;)(\\\\("|&quot;)|(?!&quot;)[^"])*("|&quot;)|((?!"|&quot;).)+/i';
$hasQuote = '/"|&quot;/i';
$word = '/\bWORD\b/';
$replacement = 'REPLACEMENT';
$n = preg_match_all($tokenizer, $target, $matches, PREG_SET_ORDER);
$newStr = '';
if ($n === false) {
    /* Print error Message */
    die();
}
foreach($matches as $match){
    if(preg_match($hasQuote, $match[0])){
        //If it has a quote, it's a quoted string.
        $newStr .= $match[0];
    } else {
        //Otherwise, run the replace.
        $newStr .= preg_replace($word, $replacement, $match[0]);
    }
}

//Now $newStr has your replaced String.  Return it from your function, or print it to
//your page.
于 2013-06-25T15:10:33.787 に答える