匹配的字符串时,如何能正则表达式忽略逃脱引号?(How can regex ignore escap

2019-09-17 05:53发布

我想写一个正则表达式将匹配一切,但尚未逃脱撇号。 考虑以下:

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

我的目标是编写一个正则表达式将在该字符串部分基本上相匹配。 我想的东西,如

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

为了匹配一个简单的字符串,但我一直在试图找出如何获得负回顾后上撇号的工作,以确保它不是由一个反斜杠...

有任何想法吗?

- JMT

Answer 1:

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


Answer 2:

下面是我的测试案例的解决方案:

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

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

需要注意的是在开始初期通配符必须非贪婪。 然后我使用非回溯匹配吞噬\\和\”,然后其他任何不是一个独立的引号字符。

我想,这大概一个模拟编译器内置的方式,这应该让漂亮防弹。



Answer 3:

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

括号内的部分看起来非撇号/反斜杠和反斜杠转义字符。 如果只有某些字符可以逃脱变化\\.\\['\\az]或任何。



Answer 4:

通过负的外观后面:

/
.*?'              #Match until '
(
 .*?              #Lazy match & capture of everything after the first apostrophe
)    
(?<!(?<!\\)\\)'   #Match first apostrophe that isn't preceded by \, but accept \\
.*                #Match remaining text
/


Answer 5:

Regex reg = new Regex("(?<!\\\\)'(?<string>.*?)(?<!\\\\)'");


Answer 6:

这是JavaScript的:

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

它...

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

只有第一次报价被捕获。 您可以捕捉在$ 2的加引号的字符串:

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



文章来源: How can regex ignore escaped-quotes when matching strings?