C# 名字的正则表达式

C# 名字的正则表达式,c#,regex,C#,Regex,我对regex非常陌生,需要regex作为我的名字,它满足以下条件: 名字只能包含字母。它可以包含空格、连字符或撇号 它必须以字母开头 所有其他字符和数字无效 特殊字符”和–不能在一起(例如,不允许使用John'-s) 特殊字符'和-前后应出现字母表(例如,不允许使用约翰的字母表) 不允许使用两个连续空格(例如,不允许使用Annia St) 有人能帮忙吗?我尝试了这个^([a-z]+['-]?[]?[a-z]+['-]?)*?[a-z]$,但它没有按预期工作。正则表达式的编写和维护是出了名的困难

我对regex非常陌生,需要regex作为我的名字,它满足以下条件:

  • 名字只能包含字母。它可以包含空格、连字符或撇号
  • 它必须以字母开头
  • 所有其他字符和数字无效
  • 特殊字符
    不能在一起(例如,不允许使用John'-s)
  • 特殊字符
    '
    -
    前后应出现字母表(例如,不允许使用约翰的字母表)
  • 不允许使用两个连续空格(例如,不允许使用Annia St)

  • 有人能帮忙吗?我尝试了这个
    ^([a-z]+['-]?[]?[a-z]+['-]?)*?[a-z]$
    ,但它没有按预期工作。

    正则表达式的编写和维护是出了名的困难

    我多年来使用的一种技术是通过使用命名的捕获组来注释我的正则表达式。它并不完美,但可以极大地帮助提高正则表达式的可读性和可维护性

    这是一个符合您要求的正则表达式

    ^(?<firstchar>(?=[A-Za-z]))((?<alphachars>[A-Za-z])|(?<specialchars>[A-Za-z]['-](?=[A-Za-z]))|(?<spaces> (?=[A-Za-z])))*$
    
    (?=[A-Za-z])(

    您可以从下面的屏幕截图中看到这个正则表达式是如何执行的

    以我给你的正则表达式为例,用你想要匹配的样本运行它,并调整它以满足你的要求。希望我给了你足够的信息,让你能够根据自己的需要定制它

    您可以使用此链接运行正则表达式

    编辑 我已经在您的评论中更新了这个问题,而不仅仅是给您代码,我将解释这个问题以及我如何修复它

    对于您的示例“samd'Joe”,如果我们运行原始正则表达式,则会发生以下情况

    ^(?<firstchar>[A-Za-z])((?<alphachars>[A-Za-z])|(?<specialchars>[A-Za-z]['-][A-Za-z])|(?<spaces> [A-Za-z]))*$
    
    ^(?[A-Za-z])(

    2)
    (?[A-Za-z])
    匹配第一个字符

    3)

    4)
    (?[A-Za-z])
    匹配空格和随后的alpha字符

    匹配使用它们匹配的字符 这就是我们遇到问题的地方。正则表达式的“特殊字符”部分匹配一个alpha字符,我们的特殊字符,然后是另一个alpha字符(
    (?[a-Za-z]['-](?=[a-Za-z]))

    关于正则表达式,你需要知道的是,每次你匹配一个字符,这个字符就会被使用。我们已经在特殊字符之前匹配了alpha字符,所以正则表达式永远不会匹配

    每个步骤实际上都是这样的:

    1)
    ^
    匹配字符串的开头

    2)
    (?[A-Za-z])
    匹配第一个字符

    3)

    4)
    (?[A-Za-z])
    匹配空格和随后的alpha字符

    然后我们只剩下以下内容

    我们无法做到这一点,因为我们的规则之一是“字母表应该出现在特殊字符‘和–’之前和之后”

    先行 正则表达式有一个叫做“前瞻”的概念。向前看允许您匹配角色而不使用它

    前瞻的语法是
    ?=
    ,后跟要匹配的内容。例如,
    ?=[A-Z]
    将查找大写字母的单个字符

    我们可以通过使用lookaheads来修复正则表达式

    1)
    ^
    匹配字符串的开头

    2)
    (?[A-Za-z])
    匹配第一个字符

    3)

    4) 现在,我们将“spaces”正则表达式改为向前看alpha字符,这样我们就不会使用它了。我们将
    (?[A-Za-z])
    更改为
    (?=[A-Za-z])
    。这将匹配空间并展望后续的alpha字符,但不会消耗它。

    5)
    (?[A-Za-z]['-][A-Za-z])
    匹配alpha字符、特殊字符和后续的alpha字符。

    6) 我们使用一个通配符多次重复匹配前面的3条规则,并一直匹配到行尾。

    我还将lookaheads添加到“firstchar”、“specialchars”和“spaces”捕获组中,我将下面的更改加粗


    ^(?(?=[A-Za-z])((?[A-Za-z]);(?[A-Za-z]['-](?=/strong>[A-Za-z])(?(?=[A-Za-z])*$

    这个简短的正则表达式应该这样做

    • ([a-zA-Z]+?)
      -表示字符串应以字母开头

    • ([-\s'][a-zA-Z]+)*?
      -表示字符串必须有连字符、空格或撇号,后跟字母

    • ^
      $
      -表示字符串的开始和结束

    这是to regex演示。

    试试这个

    ^[^- '](?=(?![A-Z]?[A-Z]))(?=(?![a-z]+[A-Z]))(?=(?!.*[A-Z][A-Z]))(?=(?!.*[- '][- '.]))(?=(?!.*[.][-'.]))[A-Za-z- '.]{2,}$
    

    您的第一句话令人困惑:“名字必须只包含字母。它可能包含空格、连字符或撇号。”如果您提供了应该匹配和不应该匹配的示例,是否更容易提供适当的答案。可能的重复项不是重复项,因为posted您不需要正则表达式。你需要解析名字,你认为你需要正则表达式。请不要将正则表达式用于此任务,尽管它可能很简洁,因此很有吸引力。不过它的不干净迟早会让你丧命的。谢谢你的快速回答和解释,这对像我这样的新手来说确实很有帮助。不幸的是,对于“Sam D'Joe”@Sumitsing,它不起作用,我已经更新了我的答案来解决问题,但也解释了问题所在以及我是如何解决的。请看一看,在使用正则表达式时了解lookaheads是很重要的,我希望你觉得它有帮助。嘿…它起作用了…谢谢。我还试着自己创建了一个-->^([a-zA-Z]+[-'\s]?)*?[a-zA-Z]$,看起来效果也不错。仍然不确定如何对其进行单元测试:)