在HTML5模式中使用负回溯和正回溯

3
我尝试查看了许多关于如何在我的HTML5模式的正则表达式函数中使用否定后顾和先行的正则指南。
我试图匹配以下模式,其中字符串必须以一个[a-z]字母开始和结束。字符串长度最长可以为30个字符。也可以包括符号:-,但不能连续出现两个-。
因此,迄今为止我想到的是这样的内容:
^[a-z][a-z(?<!-(-)?!-)]{0,28}[a-z]$

现在我无法使前瞻和后顾工作正常,而且我不确定我是否正确实现了最大30个字符。但是,我尝试以[a-z]开头和结尾,并且它可以正常工作。

一些示例字符串:

'a-b' => true
'a-' => false
'-a' => false
'a--b' => false
'ab-cd' => true
'abc' => true
'a-b-c' => true

尝试使用 ^(?!.{31})[a-z]+(?:-[a-z]+)*$。不清楚您是否只想匹配像 abc-xyz-defaaaaaa 这样的字符串,还是像 a-()*^a 这样的字符串也是有效的。请添加一些您允许和不允许的字符串示例。 - Wiktor Stribiżew
@WiktorStribiżew 好的,看起来它正在工作,你能解释一下你使用的结构吗?它似乎与我使用的完全不同。 - Gjert
@WiktorStribiżew 请查看更新,其中包含一些允许的字符串示例。 - Gjert
1
我添加了一个带有演示和解释的答案。 - Wiktor Stribiżew
2个回答

3
您可以使用此模式:
([a-z]|\b-\b){1,30}

单词边界可防止连续使用连字符或出现在字符串限制处。请注意,在模式属性中不需要使用^和$,因为它们是隐含的。演示

有一些框架可以覆盖常规的HTML5模式行为,因此最好将锚点放在它们应该的位置。 - Wiktor Stribiżew
1
@WiktorStribiżew:这个问题是关于HTML5的,而不是任何框架。如果一个框架不能够自己锚定模式,那么就不应该使用它。 - Casimir et Hippolyte
我不知道HTML5包含了这些锚点,为什么不在每种情况下都包含它们? - Gjert
@PhyCoMath:正如我之前所说,锚点是隐式的。原因可能是该模式应该描述整个字符串而不仅仅是该字符串的一部分。无论如何,即使您只想要字符串的一部分的条件,也可以构建描述具有此条件的整个字符串的模式;但是您并不总是能够构建一个简单的条件来描述整个字符串。(也许这个事实解释了这个选择)。 - Casimir et Hippolyte
这是一个五星级的答案。+1 - user557597

3

您需要使用

^(?!.{31})[a-z]+(?:-[a-z]+)*$

请查看正则表达式演示 请注意,在HTML5的pattern属性中,锚通常不是必需的,因为默认情况下模式在两侧都被锚定。 详细信息
  • ^ - 表示字符串开头。
  • (?!.{31}) - 字符串长度不能超过31个非换行字符(此(?!...)是负向先行断言,如果匹配到该模式,则匹配失败)(也可以使用正向先行断言- (?=.{1,30}$) - 它要求在字符串中必须有1到30个字符)。
  • [a-z]+ - 1个或多个小写ASCII字母。
  • (?:-[a-z]+)* - 零或多个序列:
    • - - 连字符
    • [a-z]+ - 1个或多个小写ASCII字母
  • $ - 表示字符串结尾。

你有时间解释一下?:在零个或多个段落序列中的作用吗? - Gjert
请参阅什么是非捕获组?问号后跟冒号(?:)的含义是什么?。当我们不需要访问子匹配值时,它用于分组。例如,Casimir的模式可以写成^(?:[a-z]|\b-\b){1,30}$ - Wiktor Stribiżew
谢谢,我会查看您提供的链接 :) - Gjert
您还可以查看HTML5正则表达式模式的处理方式:*pattern属性与整个值匹配,而不仅仅是任何子集(有点像它在模式开头暗示了一个^(?:,在模式结尾暗示了一个)$)* - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接