我正在尝试为表单验证创建一个正则表达式,但它总是返回true。用户必须能够添加{user|2|S}
之类的内容作为输入,但如果使用\
进行转义,也可以使用括号。
此代码现在检查左括号{
。
$regex = '/({(?=([a-zA-Z0-9]+\|[0-9]*\|(S|D[0-9]*)}))|[^{]|(?<=\\\){)*/';
if (preg_match($regex, $value)) {
return TRUE;
} else {
return FALSE;
}
可能的正确输入是:
Hello {user|1|S}, you have {amount|2|D2}
或
Hello {user|1|S}, you have {amount|2|D2} in \{the_bracket_bank\}
但是,这应该返回false:
Hello {user|1|S}, you have {amount|2}
这也是:
Hello {user|1|S}, you have {amount|2|D2} in {the_bracket_bank}
可以在这里找到一个实例:http://regexr.com?37tpu请注意,最后在lookbehind中有一个\
,PHP给了我错误消息,因为我不得不在我的额外时间中逃避它代码。
答案 0 :(得分:1)
您可以在不使用lookbehind / lookaheads(通常建议使用)的情况下为此制作正则表达式。
例如,如果您的要求是您可以匹配任何字符,只有{
和}
,除非它前面有\
。你也可以说:
匹配任何字符,但{
和}
或匹配\{
或\}
。要匹配除{
和}
之外的任何字符:
[^{}]
匹配\{
使用:
\\\{
一个反斜杠用于转义{
(这可能不是必需的,具体取决于你的正则表达式编译器),一个反斜杠用于转义另一个反斜杠。
你最终会得到这个:
(?:
[^{}]
|
\\\{
|
\\\}
)+
我很好地格式化了这个正则表达式,因此它是可读的。如果你想在你的代码中使用它,请确保使用[PCRE_EXTENDED][1]
修饰符。
答案 1 :(得分:1)
主要错误是您没有指定正则表达式应该从检查字符串的开头到匹配。使用^
和$
断言。
我认为你必须在正则表达式中逃避{
和}
,因为它们具有特殊含义。它们共同构成了量词。
(?<=\\\)
写得更好(?<=\\\\)
。反斜杠必须双重转义,因为它在单引号字符串和PCRE正则表达式中都有特殊含义。使用\\\
也可以,因为如果单引号字符串包含除\\
和\'
之外的任何转义序列,它会将其作为文字反斜杠和字母处理,因此\)
字面意思。但两次明确地避免反斜杠似乎更容易让我读到。
正则表达式应该是
$regex = '/^(\{(?=([a-zA-Z0-9]+\|[0-9]*\|(S|D[0-9]*)\}))|[^{]|(?<=\\\\)\{)*$/';
但请注意,环视断言不是必需的。这个正则表达式也应该完成这项工作:
$regex = '/^([^{]|\\\{|\{[a-zA-Z0-9]+\|[0-9]*\|(S|D[0-9]*)\})*$/';
任何非{
字符都与第一个替代字符匹配。当读取{
时,使用剩余的两个备选方案之一。大括号事物的模式匹配,或者正则表达式引擎回溯一个字符并尝试匹配\{
字符序列。如果两种方式都失败了,它会进一步回溯直到它到达字符串并完全失败。
答案 2 :(得分:0)
对我来说看起来更像是一份工作:
/((?<!\\\\)\{[a-zA-Z0-9]+\|[0-9]+\|[SD][0-9]*\})/
然而,混淆因素是如此之高,我宁愿识别所有括号内的字符串并稍后解析它们。