正则表达式只允许字符之间有破折号

Regex only allow dash in between characters

我有这个正则表达式 ^[A-ZÆØÅa-zæøå\ \-]{2,50}$ 用于验证名称。我怎样才能让它只允许一个“-”。我希望它接受这样的名称:

Janet Smith-Johnson
Mary-Ann Johnson
Sara Mary John-Smith
Sara Johnson
Sara Mary Johnson

但它不允许以 - 开头并以 - 结尾的名称。喜欢:

-Janet Mary
Mary-

您可以使用

^(?=.{2,50}$)(?!(?:.*-){2})[A-ZÆØÅa-zæøå]+(?:[- ][A-ZÆØÅa-zæøå]+)*$

参见regex demo

如果您在 C# 中使用正则表达式或在支持 ECMAScript 2018+ 标准的 JavaScript 中使用 u 标志,您还可以将任何 Unicode 字母与 \p{L} 匹配:

^(?=.{2,50}$)(?!(?:.*-){2})\p{L}+(?:[- ]\p{L}+)*$

详情:

  • ^ - 字符串开头
  • (?=.{2,50}$) - 允许在字符串中包含 2 到 50 个字符
  • (?!(?:.*-){2})(或实际代码中的 (?!(?:[^-]*-){2}) 效率更高)- 不允许使用两个连字符
  • [A-ZÆØÅa-zæøå]+ - 一组中的一个或多个字母(\p{L} 匹配任何 Unicode 字母)
  • (?:[- ][A-ZÆØÅa-zæøå]+)* - space 或 - 的零个或多个序列,然后是一个或多个字母
  • $ - 字符串结尾。

您可以在不使用 space 的情况下匹配字符 class,然后可以选择重复 space 并再次使用不使用 space 的字符 class。

然后可选地匹配 - 和相同的机制。

^(?=.{2,50}$)[A-ZÆØÅa-zæøå]+(?: [A-ZÆØÅa-zæøå]+)*(?:-[A-ZÆØÅa-zæøå]+(?: [A-ZÆØÅa-zæøå]+)*)?$

部分中的模式匹配:

  • ^ 字符串开头
  • (?=.{2,50}$) 断言 2 - 50 个字符
  • [A-ZÆØÅa-zæøå]+ 匹配不带 space
  • 的字符 class 中列出的内容
  • (?: [A-ZÆØÅa-zæøå]+)* 可以选择重复字符 class 前面有 space
  • (?:非捕获组整体匹配
    • -[A-ZÆØÅa-zæøå]+ 匹配不带 space
    • 的字符 class 中列出的内容
    • (?: [A-ZÆØÅa-zæøå]+)* 可以选择重复字符 class 前面有 space
  • )?关闭非捕获组并使其可选
  • $ 字符串结束

Regex demo