![](/img/trans.png)
[英]How do I print and store regex (Regular Expressions) in PHP and MYSQL
[英]How to evaluate constraints using regular expressions? (php, regex)
所以,假设我想接受如下字符串SomeColumn IN||<||>||= [123, 'hello', "wassup"]||123||'hello'||"yay!"
例如: MyValue IN ['value', 123]
或MyInt > 123
-> 我想你明白了。 现在,困扰我的是如何在正则表达式中表达这个? 我正在使用 PHP,这就是我现在正在做的事情:
$temp = explode(';', $constraints);
$matches = array();
foreach ($temp as $condition) {
preg_match('/(.+)[\t| ]+(IN|<|=|>|!)[\t| ]+([0-9]+|[.+]|.+)/', $condition, $matches[]);
}
foreach ($matches as $match) {
if ($match[2] == 'IN') {
preg_match('/(?:([0-9]+|".+"|\'.+\'))/', substr($match[3], 1, -1), $tempm);
print_r($tempm);
}
}
真的很感谢那里的任何帮助,我的正则表达式很糟糕。
我假设您的输入看起来与此类似:
$string = 'SomeColumn IN [123, \'hello\', "wassup"];SomeColumn < 123;SomeColumn = \'hello\';SomeColumn > 123;SomeColumn = "yay!";SomeColumn = [123, \'hello\', "wassup"]';
如果您使用preg_match_all
则不需要explode
或自己构建匹配。 请注意,生成的二维数组将切换维度,但这通常是可取的。 这是代码:
preg_match_all('/(\w+)[\t ]+(IN|<|>|=|!)[\t ]+((\'[^\']*\'|"[^"]*"|\d+)|\[[\t ]*(?4)(?:[\t ]*,[\t ]*(?4))*[\t ]*\])/', $string, $matches);
$statements = $matches[0];
$columns = $matches[1];
$operators = $matches[2];
$values = $matches[3];
也会有一个$matches[4]
但它没有真正的意义,只在正则表达式中使用。 首先,您在尝试中做错了一些事情:
(.+)
会消耗尽可能多的,任何字符。 因此,如果您在字符串值中有一些看起来像IN 13
那么您的第一次重复可能会消耗所有内容,并将其作为列返回。 它还允许在列名中使用空格和=
。 有两种方法可以解决这个问题。 要么通过附加使重复“不贪婪” ?
或者,更好的是,限制允许的字符,这样您就不能超过所需的分隔符。 在我的正则表达式中,我只允许使用字母、数字和下划线 ( \\w
) 作为列标识符。[\\t| ]
[\\t| ]
这混淆了两个概念:交替和字符类。 它的作用是“匹配制表符、管道或空格”。 在字符类中,您只需编写所有字符而无需对其进行分隔。 或者,您可以编写(\\t| )
,这在这种情况下是等效的。[.+]
我不知道你想用这个来完成什么,但它匹配一个文字.
或文字+
。 再次限制允许的字符并检查引号的正确匹配可能很有用(以避免'some string"
)现在解释一下我自己的正则表达式(您也可以将其复制到您的代码中,它会正常工作;另外,您在代码中将解释作为注释):
preg_match_all('/
(\w+) # match an identifier and capture in $1
[\t ]+ # one or more tabs or spaces
(IN|<|>|=|!) # the operator (capture in $2)
[\t ]+ # one or more tabs or spaces
( # start of capturing group $3 (the value)
( # start of subpattern for single-valued literals (capturing group $4)
\' # literal quote
[^\']* # arbitrarily many non-quote characters, to avoid going past the end of the string
\' # literal quote
| # OR
"[^"]*" # equivalent for double-quotes
| # OR
\d+ # a number
) # end of subpattern for single-valued literals
| # OR (arrays follow)
\[ # literal [
[\t ]* # zero or more tabs or spaces
(?4) # reuse subpattern no. 4 (any single-valued literal)
(?: # start non-capturing subpattern for further array elements
[\t ]* # zero or more tabs or spaces
, # a literal comma
[\t ]* # zero or more tabs or spaces
(?4) # reuse subpattern no. 4 (any single-valued literal)
)* # end of additional array element; repeat zero or more times
[\t ]* # zero or more tabs or spaces
\] # literal ]
) # end of capturing group $3
/',
$string,
$matches);
这利用了 PCRE 的递归功能,您可以在其中使用(?n)
重用子模式(或整个正则表达式(?n)
(其中n
只是您也将用于反向引用的数字)。
我可以想到可以用这个正则表达式改进的三个主要方面:
'don\\'t do this'
,我只会捕获'don\\'
)。 这可以使用否定的lookbehind来解决。?
使其可选来轻松解决)我没有包括这些,因为我不确定它们是否适用于您的问题,而且我认为正则表达式已经足够复杂,可以在这里展示。
通常正则表达式的功能不足以进行正确的语言解析。 通常最好编写解析器。
既然你说你的正则表达式很糟糕......虽然正则表达式由于其不常见的语法而看起来像是很多黑魔法,但它们并不难理解,如果你花点时间了解一下它们的基本概念。 我可以推荐这个教程。 它真的带你一路走来!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.