强制将正则表达式用两端的引号引起来或完全不引起引号,而无需复制表达式 Demo

问题描述

我有一个表达式,要么应该在两端都用引号引起来,要么根本不要,并且我想创建一个正则表达式来捕获该表达式。
关键是,我不想重复该表达式。
例如,如果表达式是英语中的任何单个字母,则重复的正则表达式将是

^[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]'?$

说明

  • ^字符串的开头
  • (?!否定前瞻,断言右侧该位置的内容不是
  • )提前关闭
  • '?[a-z]'?在可选[a-z]之间匹配'
  • $字符串结尾

Regex demo