我正在尝试用PHP制作一个正则表达式。我可以让它用其他语言工作,但不能用PHP。
我想验证数组中的项目名称
- 它们可以包含大小写字母、数字、下划线和连字符
- 它们可以包含
=>
作为一个精确的字符串,而不是单独的字符 - 它们不能从
=>
开始 - 他们不能以
=>
结束
我当前的代码:
$regex = '/^[a-zA-Z0-9-_]+$/'; // contains A-Z a-z 0-9 - _
//$regex = '([^=>]$)'; // doesn't end with =>
//$regex = '~.=>~'; // doesn't start with =>
if (preg_match($regex, 'Field_name_true2')) {
echo 'true';
} else {
echo 'false';
};
// Field=>Value-True
// =>False_name
//Bad_name_2=>
使用负环视。在开始处的负向前看(?!=>)
禁止以=>
开始,并且在结束处的负向后看(?<!=>)
禁止以=>
结束。
^(?!=>)(?:[a-zA-Z0-9-_]+(=>)?)+(?<!=>)$
演示
这里绝对不需要查找。
锚和一个可选组就足够了。
演示
/^[w-]+(?:=>[w-]+)?$/
^^^^^^^^^^^^^-- this whole non-capturing group is optional
这允许完全由[0-9a-zA-Z-]
组成的字符串或由=>
分割ONCE。
非捕获组可能出现零次或一次。
换句话说,=>
可能出现在一个或多个[w-]
字符之后,但如果确实出现了,则必须紧跟一个或更多[w-]
字符,直到字符串结束。
为了解决问题要求中的一些歧义:
如果
foo=>bar=>bam
有效,则使用/^[w-]+(?:=>[w-]+)*$/
,它将?
(零或一)替换为*
(零或更多)。如果
foo=>=>bar
有效,则使用/^[w-]+(?:(?:=>)+[w-]+)*$/
,它将=>
(必须出现一次)替换为(?:=>)+
(子字符串必须出现一或多次)。
好吧,你的字符范围等于w
,所以你可以使用
^(?!=>)(?:(?!=>$)(?:[-w]|=>))+$
这种构造使用";脾气暴躁的贪婪令牌";,请参阅regex101.com上的演示。
更闪亮、更复杂、更夸张的是,您可以使用子例程,如:
(?(DEFINE)
(?<chars>[-w]) # equals to A-Z, a-z, 0-9, _, -
(?<af>=>) # "arrow function"
(?<item>
(?!(?&af)) # no af at the beginning
(?:(?&af)?(?&chars)++)+
(?!(?&af)) # no af at the end
)
)
^(?&item)$
请参阅regex101.com上的另一个演示
对于示例数据,您可以使用
^[a-zA-Z0-9_-]+=>[a-zA-Z0-9_-]+$
模式匹配:
^
字符串开始[a-zA-Z0-9_-]+
匹配列出的任何范围或字符的1+倍(不能以=>开头)=>
按字面匹配[a-zA-Z0-9_-]+
再次匹配列出的任何范围或字符1次以上$
字符串末尾
Regex演示
如果你想允许可选空间:
^h*[a-zA-Z0-9_-]+h*=>h*[a-zA-Z0-9_-]+h*$
Regex演示
注意[a-zA-Z0-9_-]
可以写成[w-]