Ruby正则表达式允许A-Za-z0-9

时间:2019-08-09 15:48:24

标签: regex ruby

我有以下正则表达式:

/([A-Za-z0-9]+)([A-Za-z0-9\-\_]+)([A-Za-z0-9]+)/

它不能满足我的需求,即:

  • 不允许空格
  • 允许大写英文字母
  • 允许小写英文字母
  • 允许数字
  • 字符串不能同时包含连字符和下划线
  • 连字符:连字符不能位于字符串的开头或结尾; 可以有任意数量的连字符,但连续只能有1个连字符(a--b无效)。
  • 下划线:下划线不能在字符串的开头或结尾;下划线可以是任意数量,但连续只能有1个下划线(a__b无效)
  • 字符串必须包含至少1个字符(字母)

有效示例:

  • a1_b_2_hello
  • 2b-ffg-er2
  • abs
  • 123a

无效的示例:

  • _a1_b_2_hello
  • 2b-ffg_er2-
  • __
  • --
  • a__
  • b--2

4 个答案:

答案 0 :(得分:4)

我发现将所有特殊条件放在正面和负面的开始位置并遵循一般要求(在这里 @RequestMapping(path = "/employees/{employeeId}",produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}, consumes = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN}) public Employee retrievebyId(@PathVariable String employeeId) { return employeeService.retrieveEmployee(employeeId); } )(不消耗任何字符)非常方便。

[a-z\d_-]+\z

r = /
    \A           # match start of string  
    (?!.*        # begin negative lookahead and match >= 0 characters
      (?:--|__)  # match -- or __ in a non-capture group
    )            # end negative lookahead
    (?![-_])     # do not match - or _ at the beginning of the string
    (?!.*[-_]\z) # do not match - or _ at the end of the string
    (?!          # begin negative lookahead
      .*-.*_     # match - followed by _ 
      |          # or
      .*_.*-     # match _ followed by - 
    )            # end negative lookahead
    (?=.*[a-z])  # match at least one letter 
    [a-z\d_-]+   # match one or more English letters, digits, _ or -
    \z           # match end of string
    /ix          # case indifference and free-spacing modes

该正则表达式通常是这样写的:

 "a".match? r          #=> true   
 "aB32-41".match? r    #=> true
 "".match? r           #=> false (must match a letter)
 "123-4_5".match? r    #=> false (must match a letter)
 "-aB32-4_1".match? r  #=> false (cannot begin with -)
 "aB32-4_1-".match? r  #=> false (cannot end with -)
 "_aB32-4_1".match? r  #=> false (cannot begin with _)
 "aB32-4_1_".match? r  #=> false (cannot end with _)
 "aB32--4_1".match? r  #=> false (cannot contain --)
 "aB32-4__1".match? r  #=> false (cannot contain __)
 "aB32-4_1".match? r   #=> false (cannot contain both - and _)
 "123-4_5$".match?  r  #=> false ($ is not a permitted character)

答案 1 :(得分:3)

您可以在字符类中添加a-zA-Z,并重复0+次匹配连字符或下划线[-_],再匹配字符类{ {1}}。

使用具有backreference的捕获组来一致使用[A-Za-z0-9]+-

_

关于图案

  • \A[A-Za-z0-9]*[A-Za-z][A-Za-z0-9]*(?:([-_])[A-Za-z0-9]+(?:\1[A-Za-z0-9]+)*)?\z 字符串的开头
  • \A匹配至少1个a-zA-Z
  • [A-Za-z0-9]*[A-Za-z][A-Za-z0-9]*非捕获组
    • (?:捕获组1,匹配([-_])-
    • _匹配1次以上列出的内容
    • [A-Za-z0-9]+
      • (?:向第1组中捕获的内容进行反向引用\1[A-Za-z0-9]+,以获得一致的定界符(以防止匹配\1)并与列出的内容相匹配1倍以上
    • a-b_c关闭非捕获组并将其设置为可选
  • )*关闭非捕获组并将其设置为可选
  • )?字符串结尾

Regex demo

有关锚的详细说明,请参见this page

答案 2 :(得分:1)

您可以添加(?!.*(\-\-|__|_.*\-|\-.*_).*)来检查连续的破折号或下划线,并且仅在中间捕获组之前添加一种,并在所有内容之前添加(?=.*[a-z].*)来检查至少一个字符。所以整个过程看起来像:

(?=.*[a-zA-Z].*)([A-Za-z0-9]+)(?!.*(\-\-|__|_.*\-|\-.*_).*)([A-Za-z0-9\-\_]+)([A-Za-z0-9]+)

答案 3 :(得分:0)

使用先行/后置断言的解决方案

^[a-z\d](?!.*--.*)(?!.*__.*)(?!.*-.*_)(?!.*_.*-)[\w-]*(?<=[^_-])$

Click here to see demo

  • ^[a-z\d]-以任何字母或数字开头
  • (?!.*--.*)(?!.*__.*)-前瞻以确保没有__或-
    • (?!.*-.*_)(?!.*_.*-)-先行确定以确保没有_后跟-,反之亦然
  • [\w-]*-可选地匹配任何字母,数字,_-
  • (?<=[^_-])-回溯以确保其不以-或_
  • 结尾

样本数据:

# Start with a letter
a
ab
abc
abc123
abc123abc

# Has underscores
a_b
a_b_c

# Has dashes
a-b
a-b-c

# Can't start or end with an underscore or dash
_abc
abc_
abc-
-abc

# Can't contain -- or __
a__
a__b
a__b__c
d--
d--e
a--b--c

# Can only use _ or - but not both

a-_b
a-_b-_c
a-_b_-d
a-_b_____f--_-_--__