问题描述
我有一个表达式,要么应该在两端都用引号引起来,要么根本不要,并且我想创建一个正则表达式来捕获该表达式。
关键是,我不想重复该表达式。
例如,如果表达式是英语中的任何单个字母,则重复的正则表达式将是
^[a-z]|'[a-z]'$
现在a
和'a'
都将被接受。
有没有一种方法可以在不复制表达式的情况下定义此正则表达式?
解决方法
怎么样:
^('?)[a-z]\1$
在组1中,匹配'
或不匹配。在[a-z]
部分之后,匹配我们在组1(\1
)中匹配的内容。所以:
- 组1匹配
'
,在这种情况下\1
匹配'
->^'[a-z]'$
,或者; - 组1不匹配,在这种情况下
\1
不匹配->^[a-z]$
因此,这与^([a-z]|'[a-z]')$.
匹配。
Demo
,this呢?
^(?:'|(?=.*[^']$))[a-z]'?$
实际上,这是无效的,因为它也与'a
相匹配。 This更好,但也更长一些:
^(?:'(?=.*')|(?=[^']+$))[a-z]'?$
第二个有效版本的说明:
-
[a-z]'?$
与字母匹配,并可选地在行的末尾加上'
。此单引号是否存在取决于正则表达式的另一部分 -
^(?:'(?=.*')|(?=[^']+$))
与'
匹配,如果该行也以'
结尾,或者只是一串非单引号(嗯,实际上只有一个)-
(?:…)
是一个非捕获组
如果行也以 -
'
是匹配并消耗前导'
的替代方法;(?=.*')
而不是(?=.*'$)
的原因仅仅是$
已经被另一则正则表达式强加了 -
(?=[^']+$)
不会消耗任何东西,只是断言该行没有单引号
'(?=.*')
结尾,则 -
另一种选择可以断言该字符串不包含单个'
,并且使用单个否定的超前查询。
^(?![^'\r\n]*'[^'\r\n]*$)'?[a-z]'?$
说明
-
^
字符串的开头 -
(?!
否定前瞻,断言右侧该位置的内容不是-
[^'\r\n]*'[^'\r\n]*$
使用negated character class匹配一次出现的'
-
-
)
提前关闭 -
'?[a-z]'?
在可选[a-z]
之间匹配'
-
$
字符串结尾