正则表达式:匹配不在字符串开头或结尾的所有连字符或下划线

时间:2017-08-20 06:11:24

标签: ruby regex regex-lookarounds

我正在编写一些需要将字符串转换为驼峰的代码。但是,我想在代码的开头允许任何_-

我已成功使用正则表达式匹配_字符:

^(?!_)(\w+)_(\w+)(?<!_)$

当输入为:

pro_gamer #matched
#ignored
_proto 
proto_
__proto
proto__
__proto__
#matched as nerd_godess_of, skyrim
nerd_godess_of_skyrim
  

如果它看起来像nerd_godess_of,我会在第一场比赛中递归应用我的方法。

我很难将-个匹配项添加到同一个版块中,我认为只需在这样的混合中添加-就可以了:

^(?![_-])(\w+)[_-](\w+)(?<![_-])$

并且匹配如下:

super-mario #matched
eslint-path #matched
eslint-global-path #NOT MATCHED.

我想理解为什么正则表达式无法与最后一个案例相匹配,因为它对_有效。

可以找到(几乎)完整的测试输入集{{3​​}}

3 个答案:

答案 0 :(得分:3)

事实

^(?![_-])(\w+)[_-](\w+)(?<![_-])$

与&#34; eslint-global-path&#34;中的第二个连字符不匹配是因为锚^将匹配限制在第一个连字符上。此正则表达式读取,&#34;匹配行的开头,后面没有连字符或下划线,然后匹配一个或多个单词字符(包括下划线),连字符或下划线,然后匹配捕获中的一个或多个单词字符组。最后,不要在该行的末尾匹配连字符或下划线。&#34;

下划线(但不是连字符)是一个单词(\w)字符的事实完全搞砸了正则表达式。一般而言,您可能希望使用\w\p{Alpha}(或POSIX \p{Alnum}[[:alpha:]])而非使用[[:alnum:]]

试试这个。

r = /
    (?<=     # begin a positive lookbehind
      [^_-]  # match a character other than an underscore or hyphen
    )        # end positive lookbehind
    (        # begin capture group 1
      (?:    # begin a non-capture group
        -+   # match one or more hyphens
        |    # or
        _+   # match one or more underscores
      )      # end non-capture group
      [^_-]  # match any character other than an underscore or hyphen
    )        # end capture group 1
    /x       # free-spacing regex definition mode

'_cats_have--nine_lives--'.gsub(r) { |s| s[-1].upcase }
  #=> "_catsHaveNineLives--"

此正则表达式通常按如下方式编写。

r = /(?<=[^_-])((?:-+|_+)[^_-])/

如果所有字母都是小写字母,则可以写

'_cats_have--nine_lives--'.split(/(?<=[^_-])(?:_+|-+)(?=[^_-])/).
  map(&:capitalize).join
  #=> "_catsHaveNineLives--"

,其中

'_cats_have--nine_lives--'.split(/(?<=[^_-])(?:_+|-+)(?=[^_-])/)
  #=> ["_cats", "have", "nine", "lives--"]

(?=[^_-])是一个积极的先行者,需要在其上进行拆分的字符后跟一个除下划线或连字符之外的字符

答案 1 :(得分:0)

你可以试试正则表达式

^(?=[^-_])(\w+[-_]\w*)+(?=[^-_])\w$

参见演示here

答案 2 :(得分:-1)

_-切换为-_,以便-不被视为范围操作,例如a-z