首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP中的RegEx :匹配非转义引号之外的模式

PHP中的RegEx :匹配非转义引号之外的模式
EN

Stack Overflow用户
提问于 2009-05-19 17:59:54
回答 3查看 927关注 0票数 0

我正在编写一个方法来将某些数据从SQL查询字符串中提取出来,并且我需要正则化匹配大括号中的任何单词,只有当它出现在单引号之外时。我还需要它考虑转义(前有反斜杠)引号的可能性,以及转义反斜杠。

在下面的示例中,我需要正则表达式匹配{FOO}而不是{BAR}:

代码语言:javascript
复制
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字符串:

代码语言:javascript
复制
$regex = '/' .
    // Match the word in braces
    '\{(\w+)\}' .
    // Only if it is followed by an even number of single-quotes
    '(?=(?:[^\']*\'[^\']*\')*[^\']*$)' .
    // The end
    '/';

我的逻辑是,因为我解析的唯一东西是合法的SQL字符串(除了我添加的大括号外),如果一组大括号后面跟着偶数的非转义引号,那么它必须在引号之外。

除了考虑到转义引号之外,我提供的正则表达式是100%成功的。我只需要确保在引用之前没有奇数的反斜杠,但在我的生活中,我似乎无法在RegEx中表达这一点。有人接电话吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-05-19 19:51:49

处理转义引号和反斜杠的方法是以匹配的对使用它们。

代码语言:javascript
复制
(?=(?:(?:(?:[^\'\\]++|\\.)*+\'){2})*+(?:[^\'\\]++|\\.)*+$)

换句话说,在扫描下一个引号时,跳过以反斜杠开头的任何一对字符。它处理了转义引号和转义反斜杠。这种展望将允许在引用的部分之外转义字符,这可能是不必要的,但也可能不会造成伤害。

请注意拥有式量词(*+++)的自由使用;如果没有这些量词,您可能会出现性能问题,尤其是当目标字符串很大时。此外,如果字符串可以包含换行,则可能需要在DOTALL模式(也称为“单线”或"/s“模式)中进行匹配。

但是,我同意mmyers的观点:如果您试图解析SQL,您将遇到正则表达式根本无法处理的问题。在regexes不擅长的所有事情中,SQL是最差的之一。

票数 1
EN

Stack Overflow用户

发布于 2009-05-19 20:01:50

简单地,也许是天真地,str_replace把你所有的双反斜杠都去掉了。然后str_replace退出转义单引号。在这一点上,找到不位于单引号之间的匹配比较简单(例如,使用现有的regex )。

票数 0
EN

Stack Overflow用户

发布于 2009-05-19 20:24:25

如果您真的想为此使用正则表达式,我将分两个步骤:

  1. preg_split将字符串与非字符串分开:

PREG_SPLIT_DELIM_CAPTURE);

  • Replace =“$re =”(‘(?:^\’\*)*‘)“;$parts =preg_split(’/‘.$re./’,$str,-1,PREG_SPLIT_NO_EMPTY )字符串中的任何内容:

$parts as $key => $val) { if (preg_match(‘/^’.$re.‘$/,$val)) { $parts$key = preg_replace('/{(^}*)}/',’,'$1',$val);} }

但是一个真正的解析器可能会更好,因为这种方法并不是那么有效。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/884216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档