我正在尝试编写一个正则表达式,它将匹配所有内容,但没有转义的撇号。考虑以下:
<?php $s = 'Hi everyone, we\'re ready now.'; ?>
我的目标是编写一个基本匹配字符串部分的正则表达式。我正在考虑诸如
/.*'([^']).*/
为了匹配一个简单的字符串,但我一直在试图弄清楚如何在该撇号上进行否定的lookbehind工作,以确保它前面没有反斜杠......
有任何想法吗?
- JMT
我正在尝试编写一个正则表达式,它将匹配所有内容,但没有转义的撇号。考虑以下:
<?php $s = 'Hi everyone, we\'re ready now.'; ?>
我的目标是编写一个基本匹配字符串部分的正则表达式。我正在考虑诸如
/.*'([^']).*/
为了匹配一个简单的字符串,但我一直在试图弄清楚如何在该撇号上进行否定的lookbehind工作,以确保它前面没有反斜杠......
有任何想法吗?
- JMT
这是我的测试用例解决方案:
/.*?'((?:\\\\|\\'|[^'])*+)'/
还有我的(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\\'
请注意,开头的初始通配符必须是非贪婪的。然后我使用非回溯匹配来吞噬 \\ 和 \' 以及其他任何不是独立引号字符的内容。
我认为这可能模仿了编译器的内置方法,这应该使它非常防弹。
<?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\\'
/.*'([^'\\]|\\.)*'.*/
带括号的部分查找非撇号/反斜杠和反斜杠转义字符。如果只能转义某些字符,请将其更改\\.
为\\['\\a-z]
或其他。
Regex reg = new Regex("(?<!\\\\)'(?<string>.*?)(?<!\\\\)'");
这适用于 JavaScript:
/('|")(?:\\\\|\\\1|[\s\S])*?\1/
它...
\n
,\t
等)仅捕获第一个报价。您可以使用以下方法捕获 $2 中未加引号的字符串:
/('|")((?:\\\\|\\\1|[\s\S])*?)\1/