如何在 JS 中使用正则表达式(可以是字母、数字和非字母数字)查找 3 个字符的序列,'abb' 有效而 'abbb' 无效。
这个问题是我在这里提出的问题的一个变体:如何为 javascript 结合这些正则表达式。
这是错误的:/(^([0-9a-zA-Z]|[^0-9a-zA-Z]))\1\1/
,那么正确的方法是什么?
如何在 JS 中使用正则表达式(可以是字母、数字和非字母数字)查找 3 个字符的序列,'abb' 有效而 'abbb' 无效。
这个问题是我在这里提出的问题的一个变体:如何为 javascript 结合这些正则表达式。
这是错误的:/(^([0-9a-zA-Z]|[^0-9a-zA-Z]))\1\1/
,那么正确的方法是什么?
这取决于你的实际意思。如果您只想匹配三个不相同的字符(即 ifabb
对您有效),则可以使用此否定前瞻:
(?!(.)\1\1).{3}
它首先断言,当前位置后面没有三个相同的字符。然后它匹配这三个字符。
如果你真的想匹配 3 个不同的字符(只有类似的东西abc
),它会变得有点复杂。改用这两个负前瞻:
(.)(?!\1)(.)(?!\1|\2).
首先匹配一个字符。然后我们断言,this 后面不是同一个字符。如果是这样,我们匹配另一个字符。然后我们断言这些后面既不是第一个字符也不是第二个字符。然后我们匹配第三个字符。
请注意,那些负前瞻 ( (?!...)
) 不会消耗任何字符。这就是为什么它们被称为前瞻。他们只是检查接下来会发生什么(或者在这种情况下,接下来不会发生什么),然后正则表达式从它离开的地方继续。这是一个很好的教程。
另请注意,这匹配除换行符之外的任何内容,或者如果您使用 DOTALL 或 SINGLELINE 选项,则匹配任何内容。由于您使用的是 JavaScript,因此您可以通过在正则表达式结束分隔符s
之后附加来激活该选项。如果(出于某种原因)您不想使用此选项,请将.
s替换为[\s\S]
(这始终匹配任何字符)。
更新:
在评论中澄清后,我意识到您不想找到三个不相同的字符,而是想断言您的字符串不包含三个相同(且连续)的字符。
这更容易,更接近你之前的问题,因为它只需要一个负面的前瞻。我们所做的是:我们从字符串的开头搜索三个连续的相同字符。但是由于我们要断言这些不存在,我们将其包装在一个否定的前瞻中:
^(?!.*(.)\1\1)
前瞻被锚定在字符串的开头,所以这是我们将要查看的唯一位置。然后,前瞻中的模式尝试从字符串中的任何位置找到三个相同的字符(因为.*
; 相同的字符以与上一个问题相同的方式匹配)。如果模式找到了这些,则负前瞻将因此失败,因此字符串将无效。如果找不到三个相同的字符,则内部模式将永远不会匹配,因此否定前瞻将成功。
要查找非三个相同的字符,请使用正则表达式模式
([\s\S])(?!\1\1)[\s\S]{2}