【问题标题】:RegEx start and finish with letter, allow commas and dashesRegEx 以字母开头和结尾,允许逗号和破折号
【发布时间】:2017-02-13 13:22:30
【问题描述】:

我有这个正则表达式:

/^[\a-zøåæäöüß][\a-z0-9øåæäöüß]*(?:\-?[\a-z0-9øåæäöüß,]+)*$/i

它适用于像 "K61-283øÅ,æk-ken,a-sd" 这样的疯狂输入,但在 "word," 的情况下它会失败(所以,当只有一个逗号时)。

另外 - 我如何限制它应该在每个逗号或破折号之后以一个字母开头(基本上 - 每个单词)?

规则是:以字母开头,以字母数字结尾;允许使用字母数字、破折号和逗号;每个破折号或逗号后应该有一个字母

【问题讨论】:

标签: javascript regex


【解决方案1】:

你可以使用

/^[a-zøåæäöüß][a-z0-9øåæäöüß]*(?:[-,][a-zøåæäöüß][a-z0-9øåæäöüß]*)*$/i

regex demo

详情

  • ^ - 字符串开头
  • [a-zøåæäöüß] - 来自已定义集合的字母
  • [a-z0-9øåæäöüß]* - 定义集中的 0+ 个数字或字母
  • (?:[-,][a-zøåæäöüß][a-z0-9øåæäöüß]*)* - 零个或多个序列:
    • [-,] - -,
    • [a-zøåæäöüß] - 来自已定义集合的字母
    • [a-z0-9øåæäöüß]* - 定义集中的 0+ 个数字或字母
  • $ - 字符串结束。

【讨论】:

  • 这允许a0(无效)但不允许a(有效)。
  • @melpomene:为什么a0 无效?顺便说一句,ais matched.
  • a0 被“以字母开头和结尾”(以数字结尾)排除。 a 是有效的,因为它是一个以字母开头和结尾的字符串。
  • @melpomene:我明白你的意思了。老实说,我将此要求理解为“应​​以字母数字结尾”。
  • @melpomene:我在问题下方的评论中询问了 OP。
【解决方案2】:

更新 2:

有两种方法可以查看您的要求。

  1. 俯视图

    我们将输入视为一个或多个单词的列表,以逗号或破折号分隔:

    INPUT = WORD (?: [,\-] WORD )*
    

    每个单词由一个字母组成,后跟零个或多个字母或数字:

    WORD = LETTER [ LETTER DIGIT ]*
    

    翻译成 JavaScript 正则表达式语法给我们:

    WORD = [a-zøåæäöüß][a-zøåæäöüß\d]*
    

    对于整个输入(带有锚点):

    /^[a-zøåæäöüß][a-zøåæäöüß\d]*(?:[,\-][a-zøåæäöüß][a-zøåæäöüß\d]*)*$/i
    

    (这是 Wiktor Stribiżew 的回答。)

  2. 自下而上的视图

    我们首先查看允许的字符。我们知道第一个字符必须是字母。之后,可以有零个或多个输入元素:

    INPUT = LETTER ELEMENT*
    

    每个元素都是

    • 一个字母或数字,或
    • 逗号或破折号,后跟一个字母:

    ELEMENT = [ LETTER DIGIT ] | [ COMMA DASH ] LETTER
    

    把它翻译成 JavaScript 给我们:

    /^[a-zøåæäöüß](?:[a-zøåæäöüß\d]|[,\-][a-zøåæäöüß])*$/i
    

这两个正则表达式是等价的。自下而上的正则表达式更短,包含的重复代码更少。另一方面,如果输入字符串主要是字母数字,而破折号/逗号相对较少,则自上而下的正则表达式可能在某些正则表达式引擎上运行得更快。令人抓狂的是,如果您的输入很短,您可能不会关心微小的性能差异。


这是您(修改后的)要求的直接编码:

/^[a-zøåæäöüß](?:(?:[a-zøåæäöüß\d]|[,\-][a-zøåæäöüß])*[,\-]?[a-zøåæäöüß])?$/i

这个想法是匹配一个字母,然后是一个

  • 字符串的结尾(处理长度为 1 的输入字符串),或
  • 0 或多个中间体的列表,可选地后跟逗号或破折号,后跟另一个字母

每个中间体都是

  • 一封信,或
  • 一个数字,或
  • 逗号或破折号后跟一个字母

【讨论】:

  • 除非它在"asd,-asd"失败。
  • @Milkncookiez 我已经完全重写了我的答案。
  • @WiktorStribiżew 我又重写了一次。 :-)
【解决方案3】:

试试这个:(允许逗号或破折号后的字母和数字)

/^[a-zøåæäöüß]([a-z0-9øåæäöüß]|(,|-)[a-z0-9øåæäöüß])*[a-zøåæäöüß]$/i

或者这个:(允许逗号或破折号后的字母)

/^[a-zøåæäöüß]([a-z0-9øåæäöüß]|(,|-)[a-zøåæäöüß])*[a-zøåæäöüß]$/i

【讨论】:

  • 您不必逃避,-。您的正则表达式不允许a(有效),但它们允许a,0a(无效)。
  • a,a 是另一个与您的正则表达式不匹配的有效输入。
猜你喜欢
  • 2015-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多