2009-06-29 199 views
5

我想寫一個匹配所有東西的正則表達式,但是沒有被轉義的撇號。考慮以下內容:匹配字符串時,regex如何忽略轉義引號?

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

我的目標是編寫一個正則表達式,它基本上匹配字符串部分。我想的東西,如

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

爲了匹配一個簡單的字符串,但我一直在試圖找出如何獲得負回顧後上撇號的工作,以確保它不會被前面反斜槓...

任何想法?

- JMT

回答

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\\' 
2
/.*'([^'\\]|\\.)*'.*/ 

括號部分看起來對於非撇號/反斜槓和反斜槓轉義字符。如果只有某些字符可以逃脫,請將\\.更改爲​​或其他。

+0

非常接近,但不處理出現問題的情況...... – 2009-06-29 21:25:29

+0

感謝約翰「我的字符串以反斜槓\\結束」!對我來說幸運的是,我要處理的情況可以被剋制,並且永遠不會達到.jxc描述的問題。非常簡單的解決方案,我真的應該想到。再次謝謝你! :) – JMTyler 2009-06-29 21:31:59

0

通過後面負的樣子:

/ 
.*?'    #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

這裏是我的測試用例的解決方案:

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

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

注意,在最初的通配符開始需要非貪婪。然後我使用非回溯匹配來吞噬\\和\\,然後是其他任何不是獨立引用字符的東西。

我想這個可能模仿了編譯器的內置方法,這應該使它非常防彈。

0

這是JavaScript的:

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

它...

  • 比賽單或雙引號中的字符串
  • 匹配空字符串(長度爲0)
  • 匹配字符串用嵌入空白(\n,\t等)
  • 跳過內轉義引號(單或雙)雙引號內
  • 跳過單引號和反之亦然

只有第一個報價被捕獲。您可以捕捉到不帶引號的字符串中的$ 2:

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

相關問題