【问题标题】:How can regex ignore escaped-quotes when matching strings?匹配字符串时,正则表达式如何忽略转义引号?
【发布时间】:2009-06-29 21:17:21
【问题描述】:

我正在尝试编写一个正则表达式,它将匹配所有内容,但一个未转义的撇号。考虑以下几点:

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

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

之类的事情
/.*'([^']).*/

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

有什么想法吗?

-JMT

【问题讨论】:

    标签: regex escaping negative-lookbehind


    【解决方案1】:

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

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

    还有我的(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\\'
    

    请注意,开头的初始通配符必须是非贪婪的。然后我使用非回溯匹配来吞噬 \\ 和 \' 以及其他任何不是独立引号字符的内容。

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

    【讨论】:

      【解决方案2】:
      <?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\\'
      

      【讨论】:

      • 投票支持,因为您提供了测试用例。
      【解决方案3】:
      /.*'([^'\\]|\\.)*'.*/
      

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

      【讨论】:

      • 非常接近,但这不能处理病态的情况......'我的字符串以反斜杠结尾\\'
      • 谢谢约翰!对我来说幸运的是,我将不得不处理的案例可以得到限制,并且永远不会遇到.jxc 描述的问题。非常简单的解决方案,我真的应该想到。再次谢谢你! :)
      【解决方案4】:
      Regex reg = new Regex("(?<!\\\\)'(?<string>.*?)(?<!\\\\)'");
      

      【讨论】:

        【解决方案5】:

        这是针对 JavaScript 的:

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

        它...

        • 匹配单引号或双引号字符串
        • 匹配空字符串(长度为0)
        • 匹配带有嵌入空格的字符串(\n、\t 等)
        • 跳过内部转义引号(单引号或双引号)
        • 在双引号内跳过单引号,反之亦然

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-05-12
          • 1970-01-01
          • 1970-01-01
          • 2021-01-31
          • 2011-09-25
          • 2012-07-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多