输入字符串由字母I N P U Y X
组成- 我必须验证它只包含这些字母而在PERL regexp
中没有其他内容- 验证该输入还包含至少2次出现的“NP”(不含引号)
示例字符串:
INPYUXNPININNPXX
字符串都是大写的
答案 0 :(得分:4)
您可以在PCRE中使用这个基于前瞻性的正则表达式:
^(?=(?:.*?NP){2})[INPUYX]+$
<强>解释强>
^ assert position at start of a line
(?=(?:.*?NP){2}) Positive Lookahead - Assert that the regex below can be matched
(?:.*?NP){2} Non-capturing group
Quantifier: Exactly 2 times
.*? matches any character (except newline)
Quantifier: Between zero and unlimited times, as few times as possible, expanding as needed [lazy]
NP matches the characters NP literally (case sensitive)
[INPUYX]+ match a single character present in the list below
Quantifier: Between one and unlimited times, as many times as possible, giving back as needed [greedy]
INPUYX a single character in the list INPUYX literally (case sensitive)
$ assert position at end of a line
答案 1 :(得分:1)
使用此:
^[INPUYX]*NP[INPUYX]*?NP[INPUYX]*$
查看实际操作:http://regex101.com/r/vI2xQ6
实际上我们在这里做的是允许你的0个或更多个字符类,捕获NP的第一个(必需的)出现,然后确保它在字符串结束之前至少再次出现。
假设你想要捕捉中间,你可以这样做:
^(?=(?:(.*?)NP){2})[INPUYX]+$
或者@ikegami指出(仅匹配单行)\A(?=(?:(.*?)NP){2})[INPUYX]+\z
。
答案 2 :(得分:1)
最干净的解决方案是:
/^[INPUXY]*\z/ && /NP.*NP/s
以下是最有效的,因为它避免了两次匹配字符串,并且它可以防止在失败时回溯:
/
^
(?: (?:[IPUXY]|N[IUXY])* NP ){2}
[INPUXY]*
\z
/x
要捕捉两个NP之间的内容,您可以使用
/
^
(?:[IPUXY]|N[IUXY])* NP
( (?:[IPUXY]|N[IUXY])* ) NP
[INPUXY]*
\z
/x