如何设置正则表达式部分的最大长度?

时间:2021-07-06 16:19:33

标签: regex

^[A]+(C[A]+)*.....$ 我表达式末尾的句点是我的正则表达式的延续 是否可以在此段 (^[A]+(C[A]+)*) 上设置最大长度?

感谢您的回答

3 个答案:

答案 0 :(得分:0)

您只能定义字符和字符类的长度,或者一个组可以重复的最小/最大次数。因此,在您的示例中,[A]+ 的范围可以限定为更精确的长度,并且内部带星号和外部组都可以限定为多次重复。

但是,一些正则表达式库具有 added push-down automata features 或不属于传统正则表达式的语言挂钩。使用这些类型的扩展,可能会在超过定义的限制时计算字符数并停止匹配。

答案 1 :(得分:0)

是的,如果您知道在该段之后必须出现什么或不能出现什么,您可以使用正向前瞻来执行此操作,或者您可以使用后视(如果支持)。

例如,如果您想将正则表达式 ^[A]+(C[A]+)*^[A]+(C[A]+)*.....$ 段限制为 5 个字符,并且您确定不能有 AC紧跟其后的字符,您可以使用:

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])规定段的长度必须在15个字符之间,并且后跟一个不是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 demoJava 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}!`) }
  }
)

相关问题