下划线或连字符的正则表达式模式,但不包括两者同时出现

4

我有一个正则表达式,允许字符串独立存在,也可以由连字符和下划线分隔。

我需要帮助使字符串只能使用连字符或下划线,但不能同时使用两者。

这是我目前的情况。

^([a-z][a-z0-9]*)([-_]{1}[a-z0-9]+)*$

foo             = passed
foo-bar         = passed
foo_bar         = passed
foo-bar-baz     = passed
foo_bar_baz     = passed
foo-bar_baz_qux = passed # but I don't want it to
foo_bar-baz-quz = passed # but I don't want it to

请展示您正在使用正则表达式的代码。 - Wiktor Stribiżew
请注意,如果您想匹配 a-zA-Z0-9_,您可以使用 \w 来代替。 - ElChiniNet
2个回答

4
你可以扩展这个模式并使用反向引用来仅匹配相同的分隔符:
^[a-z][a-z0-9]*(?:([-_])[a-z0-9]+(?:\1[a-z0-9]+)*)?$

请参阅正则表达式演示

详细信息:

  • ^ - 字符串的开头
  • [a-z][a-z0-9]* - 一个字母后面跟着0个或多个小写字母或数字
  • (?:([-_])[a-z0-9]+(?:\1[a-z0-9]+)*)? - 可选序列:
    • ([-_]) - 捕获组1匹配“-”或“_”
    • [a-z0-9]+ - 1个或多个小写字母或数字
    • (?:\1[a-z0-9]+)* - 0个或多个序列:
      • \1 - 与捕获组1中相同的值
      • [a-z0-9]+ - 1个或多个小写字母或数字
  • $ - 字符串的结尾。

当在C字符串字面量中声明时,反斜杠必须加倍:String s = "^[a-z][a-z0-9]*(?:([-_])[a-z0-9]+(?:\\1[a-z0-9]+)*)?$"(Java)。 - Wiktor Stribiżew

3
这里有一个简洁的解决方案:
^([a-zA-Z-]+|[a-zA-Z_]+)$

拆分它!

  • ^ 从文本开头开始
  • [a-zA-Z-]+ 匹配任何 a-zA-Z- 的内容
  • | 或运算符
  • [a-zA-Z_]+ 匹配任何 a-zA-Z_ 的内容
  • $ 到达文本结尾

这里是regexr上的一个例子!


为什么我的工作效果更差?这个 ^([a-zA-Z-]+|[a-zA-Z_]+)$ 实际上并没有保留最初的要求。 - Wiktor Stribiżew
你只需要在每一边加一个字符,比如:^[a-zA-Z_]([a-zA-Z-]+|[a-zA-Z_]+)[a-zA-Z_]$ - Aaron N. Brock
@WiktorStribiżew,你的方法也非常好。但是我正在尝试通过一个CSS解析器来使用它,当我想要查找第一个匹配字符“-”或“_”时,该解析器不知道“/1”是什么。 - Doctor06
1
@WiktorStribiżew 你是对的。那是一个字符串字面量,双反斜杠起作用了。 - Doctor06
伙计,我得打得更快 x) - Aaron N. Brock
显示剩余3条评论

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