^[A]+(C[A]+)*.....$
我表达式末尾的句点是我的正则表达式的延续
是否可以在此段 (^[A]+(C[A]+)*
) 上设置最大长度?
感谢您的回答
答案 0 :(得分:0)
您只能定义字符和字符类的长度,或者一个组可以重复的最小/最大次数。因此,在您的示例中,[A]+
的范围可以限定为更精确的长度,并且内部带星号和外部组都可以限定为多次重复。
但是,一些正则表达式库具有 added push-down automata features 或不属于传统正则表达式的语言挂钩。使用这些类型的扩展,可能会在超过定义的限制时计算字符数并停止匹配。
答案 1 :(得分:0)
是的,如果您知道在该段之后必须出现什么或不能出现什么,您可以使用正向前瞻来执行此操作,或者您可以使用后视(如果支持)。
例如,如果您想将正则表达式 ^[A]+(C[A]+)*
的 ^[A]+(C[A]+)*.....$
段限制为 5 个字符,并且您确定不能有 A
或 C
紧跟其后的字符,您可以使用:
const rx = /^(?=.{1,5}[^AC])[A]+(C[A]+)*.....$/;
console.log(rx.test('AAACAxxxxx')); // true (5 character segment)
console.log(rx.test('AAAACAxxxxx')); // false (6 character segment)
console.log(rx.test('AAAAACxxxx'));
// false (5 character segment, but followed by C)
正向前瞻(?=.{1,5}[^AC])
规定段的长度必须在1
和5
个字符之间,并且后跟一个不是A
或{{的字符1}}。
再看上面的最后一个例子,测试返回 C
但我们希望它返回 false
因为 true
does 匹配模式 {{1 }} 和匹配段 'AAAAACxxxx'
的子串 ^[A]+(C[A]+)*.....$
的长度不超过 5 个字符。
为了解决这种边缘情况,我们可以用 AAAAA
替换前瞻中的 ^[A]+(C[A]+)*
,这样它就允许 [^AC]
作为该段后面的字符,只要它后面没有 {{ 1}}。
([^AC]|C[^A])
你能想出一个字符串,上面的正则表达式匹配它不应该匹配,或者不匹配它应该匹配吗?
答案 2 :(得分:0)
让我们想象一下图案的最大长度是 10。
在 .NET 和 Python PyPi regex
中使用无限宽度后视模式,或者在 Java 中使用所有格量词/原子组,您可以使用:
^A++(CA++)*+(?<=^.{1,10}).*
^(?>A+(CA+)*)(?<=^.{1,10}).*
参见 .NET regex demo 和 Java regex demo。
^A++(CA++)*+(?<=^.{1,10})
正则表达式表示
^A++
- 从字符串开头匹配一个或多个 A
(由于所有格量词,不允许回溯到 A++
模式)(CA++)*+
- 匹配零次或多次(不允许回溯)的 C
和一个或多个 A
(再次,所有格匹配)(?<=^.{1,10})
- 一个正向后视,需要 1 到 10 个字符而不是从字符串开头到当前位置左侧的换行符。在不支持占用量词的 .NET 正则表达式中,原子组 ((?>...)
) 用于防止回溯到组内的模式。
如果您使用另一种不支持这些结构的正则表达式,最简单和最可行的方法是捕获要对其施加最大字符限制的模式,一旦获得有效匹配,请检查 Group 1 值长度。也就是说,像
const texts = ['AACAACAAAA123','AAAACAAAAACAA123456'];
const re = /^(A+(CA+)*).*$/;
texts.forEach( x => {
const match = x.match(re)
if (match) {
console.log(x, '=>', (match[1].length < 11 ? `${x} is valid!` : `${x} is not valid!`))
} else { console.log(`No match in ${x}!`) }
}
)