5

私はすべてに一致する正規表現を書き込もうとしていますが、エスケープされていないアポストロフィです。次のことを考慮してください。

<?php $s = 'Hi everyone, we\'re ready now.'; ?>

私の目標は、その文字列部分に本質的に一致する正規表現を作成することです。私は次のようなことを考えています

/.*'([^']).*/

単純な文字列と一致させるために、しかし私は、そのアポストロフィの前にバックスラッシュがないことを確認するために、そのアポストロフィにネガティブルックビハインドを適用する方法を見つけようとしています...

何か案は?

-JMT

4

5 に答える 5

4

テストケースを使用した私のソリューションは次のとおりです。

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

そして私の(Perlですが、私が考えていないPerl固有の機能は使用していません)証明:

use strict;
use warnings;

my %tests = ();
$tests{'Case 1'} = <<'EOF';
$var = 'My string';
EOF

$tests{'Case 2'} = <<'EOF';
$var = 'My string has it\'s challenges';
EOF

$tests{'Case 3'} = <<'EOF';
$var = 'My string ends with a backslash\\';
EOF

foreach my $key (sort (keys %tests)) {
    print "$key...\n";
    if ($tests{$key} =~ m/.*?'((?:\\\\|\\'|[^'])*+)'/) {
        print " ... '$1'\n";
    } else {
        print " ... NO MATCH\n";
    }
}

これを実行すると、次のように表示されます。

$ perl a.pl
Case 1...
 ... 'My string'
Case 2...
 ... 'My string has it\'s challenges'
Case 3...
 ... 'My string ends with a backslash\\'

開始時の最初のワイルドカードは貪欲でない必要があることに注意してください。次に、バックトラッキング以外の一致を使用して\\と\'を取得し、スタンドアロンの引用文字ではないものをすべて使用します。

これはおそらくコンパイラの組み込みアプローチを模倣していると思います。これにより、かなりの防弾性能が得られるはずです。

于 2009-06-29T21:46:02.933 に答える
3
<?php
$backslash = '\\';

$pattern = <<< PATTERN
#(["'])(?:{$backslash}{$backslash}?+.)*?{$backslash}1#
PATTERN;

foreach(array(
    "<?php \$s = 'Hi everyone, we\\'re ready now.'; ?>",
    '<?php $s = "Hi everyone, we\\"re ready now."; ?>',
    "xyz'a\\'bc\\d'123",
    "x = 'My string ends with with a backslash\\\\';"
    ) as $subject) {
        preg_match($pattern, $subject, $matches);
        echo $subject , ' => ', $matches[0], "\n\n";
}

プリント

<?php $s = 'Hi everyone, we\'re ready now.'; ?> => 'Hi everyone, we\'re ready now.'

<?php $s = "Hi everyone, we\"re ready now."; ?> => "Hi everyone, we\"re ready now."

xyz'a\'bc\d'123 => 'a\'bc\d'

x = 'My string ends with with a backslash\\'; => 'My string ends with with a backslash\\'
于 2009-06-29T21:34:40.910 に答える
2
/.*'([^'\\]|\\.)*'.*/

括弧で囲まれた部分は、アポストロフィ/バックスラッシュおよびバックスラッシュでエスケープされた文字を探します。特定の文字のみをエスケープできる場合は、\\.\\['\\a-z]、などに変更します。

于 2009-06-29T21:21:11.437 に答える
0
Regex reg = new Regex("(?<!\\\\)'(?<string>.*?)(?<!\\\\)'");
于 2009-06-29T21:36:45.010 に答える
0

これはJavaScript用です:

/('|")(?:\\\\|\\\1|[\s\S])*?\1/

それ...

  • 一重引用符または二重引用符で囲まれた文字列に一致します
  • 空の文字列に一致(長さ0)
  • 空白が埋め込まれた文字列に一致します(\n\tなど)
  • 内側のエスケープされた引用符をスキップします(シングルまたはダブル)
  • 二重引用符内の単一引用符をスキップし、その逆も同様です。

最初の見積もりの​​みがキャプチャされます。引用符で囲まれていない文字列を$2でキャプチャするには、次のコマンドを使用します。

/('|")((?:\\\\|\\\1|[\s\S])*?)\1/

于 2015-07-02T10:13:25.713 に答える