我需要解析一些用户输入。他们以条款ex:
的形式来找我total>=100
name="foo"
bar!="baz"
我有一个包含所有可用运算符(<, >, <=, !=, =
等)的列表,并使用它来构建正则表达式模式。
我的目标是将每个条款分成3部分:
$result=["total", ">=", "100"]
$result=["name", "=", "foo"]
$result=["bar", "!=", "baz"]
我的模式采用所有运算符并构建类似的东西(缩写为长度)(此示例仅匹配>
和>=
:
preg_split("/(?<=>)|(?=>)|(?<=>=)|(?=>=)/", $clause,3)
因此每个运营商都有一个后视和前瞻。如果字符串包含操作符(preg_split
),我将name="<wow>"
限制为3个组。
我的正则表达式工作得非常好,但是对于包含另一个运算符中的字符的任何运算符,它都非常失败。例如,>=
永远不会被拆分,因为>
匹配并首先拆分。与!=
=
也是如此
这是我得到的:
$result=["total", ">", "=100"]
$result=["bar", "!", "=baz"]
是否可以使用正则表达式来做我尝试的事情?我需要跟踪操作员并且不能简单地将字符串拆分(因此是前瞻/后方解决方案)。
我考虑过的一种可能性是在所有运算符周围强制使用空格或不寻常的字符,以便>
和>=
成为{>}
和{>=}
,如果正则表达式有为了匹配括号,那么它就不能像现在一样提前匹配。但是,这不是一个优雅的解决方案,看起来这里的一些正则表达式大师可能知道更好的方法。
正则表达式是最佳解决方案还是我应该使用字符串函数?
这个问题有些类似,但我不相信答案的伪代码是准确的 - 我无法让它运作良好。 How to manipulate and validate string containing conditions that will be evaluated by php
答案 0 :(得分:1)
我建议匹配而不是拆分,因为结果仍然是数组。
^(.*?)([!<>=|]=?)(.*?)$
这是demo。
$re = "/^(.*?)([!<>=|]=?)(.*?)$/m";
$str = "total>=100\nname=\"foo\"\nbar!=\"baz\"";
preg_match_all($re, $str, $matches);
print_r($matches);
输出:
Array
(
[0] => Array
(
[0] => total>=100
[1] => name="foo"
[2] => bar!="baz"
)
[1] => Array
(
[0] => total
[1] => name
[2] => bar
)
[2] => Array
(
[0] => >=
[1] => =
[2] => !=
)
[3] => Array
(
[0] => 100
[1] => "foo"
[2] => "baz"
)
)
答案 1 :(得分:0)
在每一行使用带有/([^<=>!]*)([<=>!]{1,2})(.*)/
的正则表达式preg_match
将获得所需的结果;至少对你的例子来说,但可能更多。
我认为一种有用且可能你不知道的语法是[]
。
[...]
表示匹配大括号中的任何字符
[^...]
表示匹配任何不在大括号中的字符
代码示例
$test = 'total>=100';
$regex = '/([^<=>!]*)([<=>!]{1,2})(.*)/';
preg_match($regex, $test, $match);
print_r($match);
结果:
array(4
0 => total>=100
1 => total
2 => >=
3 => 100
)
答案 2 :(得分:0)
你可以试试这个正则表达式
/^(.*)([><!]?[=]+|[>]+|[<]+)(.*)$/mgU
我在这里尝试过:https://regex101.com/输入:
xxx>"sdads"
yyy<"sadasd"
name="foo"
total>=100
total<=100
total<=100
bar!="baz"
它匹配到位的所有内容