[英]PHP: Regex to ignore escaped quotes within quotes
我在發布之前查看了相關問題,但我無法修改任何相關答案以使用我的方法(不擅長正則表達式)。
基本上,這是我現有的線路:
$code = preg_replace_callback( '/"(.*?)"/', array( &$this, '_getPHPString' ), $code );
$code = preg_replace_callback( "#'(.*?)'#", array( &$this, '_getPHPString' ), $code );
它們都匹配包含在''
和""
之間''
字符串。 我需要正則表達式來忽略它們之間包含的轉義引號。 因此''
之間''
數據將忽略\\'
而""
之間的數據將忽略\\"
。
任何幫助將不勝感激。
對於大多數字符串,您需要允許轉義任何內容(不僅僅是轉義引號)。 例如,您很可能需要允許像"\\n"
和"\\t"
這樣的轉義字符,當然還有轉義符: "\\\\"
。
這是一個常見問題,很久以前就已解決(和優化)。 Jeffrey Friedl 在他的經典著作《 掌握正則表達式(第 3 版)》中(作為示例)深入探討了這個問題。 這是您正在尋找的正則表達式:
"([^"\\\\]|\\\\.)*"
版本 1:工作正常但效率不高。
"([^"\\\\]++|\\\\.)*"
或"((?>[^"\\\\]+)|\\\\.)*"
版本 2:如果您有所有格量詞或原子組,效率會更高(請參閱:使用原子組方法的 sin 正確答案)。
"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"
版本 3:效率更高。 實現 Friedl 的: “展開循環”技術。 不需要所有格或原子組(即這可以在 Javascript 和其他功能較少的正則表達式引擎中使用。)
以下是雙引號和單引號子字符串的 PHP 語法中推薦的正則表達式:
$re_dq = '/"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"/s';
$re_sq = "/'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'/s";
試試這樣的正則表達式:
'/"(\\\\[\\\\"]|[^\\\\"])*"/'
一個(簡短的)解釋:
" # match a `"`
( # open group 1
\\\\[\\\\"] # match either `\\` or `\"`
| # OR
[^\\\\"] # match any char other than `\` and `"`
)* # close group 1, and repeat it zero or more times
" # match a `"`
以下片段:
<?php
$text = 'abc "string \\\\ \\" literal" def';
preg_match_all('/"(\\\\[\\\\"]|[^\\\\"])*"/', $text, $matches);
echo $text . "\n";
print_r($matches);
?>
產生:
abc "string \\ \" literal" def
Array
(
[0] => Array
(
[0] => "string \\ \" literal"
)
[1] => Array
(
[0] => l
)
)
這有可能:
/"(?>(?:(?>[^"\\\\]+)|\\\\.)*)"/
/'(?>(?:(?>[^'\\\\]+)|\\\\.)*)'/
基於一些粗略的基准測試,這似乎與展開循環一樣快,但更容易閱讀和理解。 它首先不需要任何回溯。
"[^"\\]*(\\.[^"\\]*)*"
這將把引號留在外面
(?<=['"])(.*?)(?=["'])
並使用global
/g 將匹配所有組
根據W3資源: https : //www.w3.org/TR/2010/REC-xpath20-20101214/#doc-xpath-StringLiteral
一般的正則表達式是:
"(\\.|[^"])*"
(+捕獲組第一次檢查時不需要加反斜杠)
解釋:
"..."
引號之間的任何匹配(...)*
內部可以有從 0 到 Infinity 的任意長度\\\\.|[^"]
首先接受任何后面有斜杠的字符 | (或) 然后接受任何不是引號的字符PHP 版本的正則表達式具有更好的分組功能,可以更好地處理Any Quotes可以是這樣的:
<?php
$str='"First \\" \n Second" then \'This \\\' That\'';
echo $str."\n";
// "First \" \n Second" then 'This \' That'
$RX_inQuotes='/"((\\\\.|[^"])*)"/';
preg_match_all($RX_inQuotes,$str,$r,PREG_SET_ORDER);
echo $r[0][1]."\n";
// First \" \n Second
$RX_inAnyQuotes='/("((\\\\.|[^"])*)")|(\'((\\\\.|[^\'])*)\')/';
preg_match_all($RX_inAnyQuotes,$str,$r,PREG_SET_ORDER);
echo $r[0][2]." --- ".$r[1][5];
// First \" \n Second --- This \' That
?>
試試看: http : //sandbox.onlinephpfunctions.com/code/4328cc4dfc09183f7f1209c08ca5349bef9eb5b4
重要提示:在這個時代,對於不確定的內容,您必須在正則表達式的末尾使用u
標志,如/.../u
以避免破壞multi-byte
字符串(如UTF-8
)或函數(如mb_ereg_match ) 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.