首页 文章

当匹配字符串时,正则表达式如何忽略转义引号?

提问于
浏览
5

我正在尝试编写一个匹配所有内容的正则表达式但是没有被转义的撇号 . 考虑以下:

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

我的目标是编写一个基本匹配字符串部分的正则表达式 . 我在考虑像

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

为了匹配一个简单的字符串,但我一直试图弄清楚如何在撇号上得到负面的lookbehind,以确保它没有反斜杠......

有任何想法吗?

  • JMT

6 回答

  • 0
    <?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\\'
    
  • 0

    这是我的测试用例解决方案:

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

    和我(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\\'
    

    请注意,开头的初始通配符需要非贪婪 . 然后我使用非回溯匹配来吞噬\和',然后是其他任何不是独立引号字符的东西 .

    我认为这个可能模仿编译器的内置方法,这应该使它非常防弹 .

  • 3
    /.*'([^'\\]|\\.)*'.*/
    

    带括号的部分查找非撇号/反斜杠和反斜杠转义字符 . 如果只能转义某些字符,请将 \\. 更改为 \\['\\a-z] ,或者其他任何内容 .

  • 2

    通过负面看后面:

    /
    .*?'              #Match until '
    (
     .*?              #Lazy match & capture of everything after the first apostrophe
    )    
    (?<!(?<!\\)\\)'   #Match first apostrophe that isn't preceded by \, but accept \\
    .*                #Match remaining text
    /
    
  • 0
    Regex reg = new Regex("(?<!\\\\)'(?<string>.*?)(?<!\\\\)'");
    
  • 3

    这适用于JavaScript:

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

    它...

    • 匹配单引号或双引号字符串

    • 匹配空字符串(长度为0)

    • 匹配嵌入空格的字符串( \n\t 等)

    • 跳过内部转义引号(单引号或双引号)

    • 在双引号内跳过单引号,反之亦然

    仅捕获第一个引用 . 您可以使用以下内容捕获$ 2中未加引号的字符串:

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

相关问题