我正在编写一个方法来将某些数据从SQL查询字符串中提取出来,并且我需要正则化匹配大括号中的任何单词,只有当它出现在单引号之外时。我还需要它考虑转义(前有反斜杠)引号的可能性,以及转义反斜杠。
在下面的示例中,我需要正则表达式匹配{FOO}而不是{BAR}:
blah blah {FOO} blah 'I\'m typing {BAR} here with an escaped backslash \\'
blah blah {FOO} 'Three backslashes {BAR} and an escaped quote \\\\\\\' here {BAR}'我在PHP中使用preg_match来获取大括号中的单词(本例中为“FOO”)。下面是到目前为止的regex字符串:
$regex = '/' .
// Match the word in braces
'\{(\w+)\}' .
// Only if it is followed by an even number of single-quotes
'(?=(?:[^\']*\'[^\']*\')*[^\']*$)' .
// The end
'/';我的逻辑是,因为我解析的唯一东西是合法的SQL字符串(除了我添加的大括号外),如果一组大括号后面跟着偶数的非转义引号,那么它必须在引号之外。
除了考虑到转义引号之外,我提供的正则表达式是100%成功的。我只需要确保在引用之前没有奇数的反斜杠,但在我的生活中,我似乎无法在RegEx中表达这一点。有人接电话吗?
发布于 2009-05-19 19:51:49
处理转义引号和反斜杠的方法是以匹配的对使用它们。
(?=(?:(?:(?:[^\'\\]++|\\.)*+\'){2})*+(?:[^\'\\]++|\\.)*+$)换句话说,在扫描下一个引号时,跳过以反斜杠开头的任何一对字符。它处理了转义引号和转义反斜杠。这种展望将允许在引用的部分之外转义字符,这可能是不必要的,但也可能不会造成伤害。
请注意拥有式量词(*+和++)的自由使用;如果没有这些量词,您可能会出现性能问题,尤其是当目标字符串很大时。此外,如果字符串可以包含换行,则可能需要在DOTALL模式(也称为“单线”或"/s“模式)中进行匹配。
但是,我同意mmyers的观点:如果您试图解析SQL,您将遇到正则表达式根本无法处理的问题。在regexes不擅长的所有事情中,SQL是最差的之一。
发布于 2009-05-19 20:01:50
简单地,也许是天真地,str_replace把你所有的双反斜杠都去掉了。然后str_replace退出转义单引号。在这一点上,找到不位于单引号之间的匹配比较简单(例如,使用现有的regex )。
发布于 2009-05-19 20:24:25
如果您真的想为此使用正则表达式,我将分两个步骤:
preg_split将字符串与非字符串分开:PREG_SPLIT_DELIM_CAPTURE);
$parts as $key => $val) { if (preg_match(‘/^’.$re.‘$/,$val)) { $parts$key = preg_replace('/{(^}*)}/',’,'$1',$val);} }
但是一个真正的解析器可能会更好,因为这种方法并不是那么有效。
https://stackoverflow.com/questions/884216
复制相似问题