2

私のPHPコードは次のようになります。

$input = "City.name = 'ニューヨーク'";
$literal_pattern = '/\'.[^\']*\'/';
preg_match($literal_pattern, $input, $token);
echo $トークン[0]; // 「ニューヨーク」を表示

私の正規表現は、次のようなエスケープされた一重引用符でリテラルを取得する必要があります。

$input = "City.name = 'New \' York'";
$literal_pattern = ???????????;
preg_match($literal_pattern, $input, $token);
echo $トークン[0]; // 'New \' York' と出力する必要があります

$literal_pattern の正規表現は何になりますか?

4

4 に答える 4

6

この条件がなければ、単純に...

/('[^']*')/

...もちろん、これで十分です。「一重引用符の後に任意の数の非一重引用符が続き、その後に再び一重引用符が続く」というすべてのシーケンスに一致します。

しかし、ここでは「通常」と「エスケープ」の 2 つの準備が必要です。したがって、パターンにスパイスを追加する必要があります。

/('[^'\\]*(?:\\.[^'\\]*)*')/

奇妙に見えるかもしれませんが (実際にそうです)、実際には非常に単純です: マッチ シーケンス...

  • 一重引用符...
  • ...0 個以上の「通常の」文字が続く ('またはではない\)、
  • ...(「エスケープされた」シンボル、次にゼロ個以上の「通常の」シンボル)の部分式が続き、0回以上繰り返されます...
  • 単一引用符記号が続きます。

例:

$input   = "City.name = 'New \\' York (And Some Backslash Fun)\\\\'\\'"; 
# ...as \' in any string literal will be parsed as a _single_ quote

$pattern = "/('[^'\\\\]*(?:\\\\.[^'\\\\]*)*')/";
# ... a choice: escape either slashes or single quotes; I choose the former

preg_match($pattern, $input, $token);
echo $token[0]; // 'New \' York (And Some Backslash Fun)\\'
于 2012-11-06T23:55:25.167 に答える
2

これはあなたが探している正規表現です:/\'(\\.|[^\'\\])*\'/

PHP では、これは次のようになります。$literal_pattern = '/(\'(?:\\.|[^\'\\])*\')/';

于 2012-11-07T00:00:22.807 に答える
1

正規表現は自動的に貪欲であるため、リテラルを使用してできるだけ多くのデータをキャッチします。したがって、「's の間のすべて」を認識すると、 first と last の間のすべてがキャッチされ'ます。

したがって、これを安全に行うことができます。

$literal_pattern = "#('.*')#";

例: http://ideone.com/gI5bXs

NB: @m.buettnerが指摘したように、このメソッドは'、入力に -encased 文字列が 1 つある場合にのみ機能します。

于 2012-11-06T23:56:38.573 に答える
0

否定後読みマッチングを使用できます。http://www.regular-expressions.info/lookaround.html

(?<!a)b否定後読みを使用して、「a」が前にない「b」に一致します

唯一のことは、PHP 正規表現がそれをサポートしていないことを確信しているということです。それらがサポートされている場合、正規表現は次のようになります。

/(?<!\\)'(.*?)(?<!\\)'/

私のアドバイスは、単純なパーサーを使用することです。これは私が頭のてっぺんから作ったものです(明らかに疑似コードで):そのロジックがあなたの目的で機能するという保証はありませんが、実際に自分で構築するのはそれほど難しくありません.

let inString = false
let escaping = false
let match = ''    
for each letter in string
    if letter == "\\" and not escaping
        escaping = true
    else
        if letter == "'" and not escaping
            inString = not inString
        else if inString
            match += letter
        escaping = false
return match
于 2012-11-07T00:15:38.840 に答える