ruby - Regex: Match all hyphens or underscores not at the beginning or the end of the string -
i writing code needs convert string camel case. however, want allow _
or -
@ beginning of code.
i have had success matching _
character using regex here:
^(?!_)(\w+)_(\w+)(?<!_)$
when inputs are:
pro_gamer #matched #ignored _proto proto_ __proto proto__ __proto__ #matched nerd_godess_of, skyrim nerd_godess_of_skyrim
i recursively apply method on first match if looks
nerd_godess_of
.
i having troubled adding -
matches same, assumed adding -
mix work:
^(?![_-])(\w+)[_-](\w+)(?<![_-])$
and matches this:
super-mario #matched eslint-path #matched eslint-global-path #not matched.
i understand why regex fails match last case given worked correctly _
.
the (almost) full set of test inputs can found here
the fact that
^(?![_-])(\w+)[_-](\w+)(?<![_-])$
does not match second hyphen in "eslint-global-path" because of anchor ^
limits match on first hyphen only. regex reads, "match beginning of line, not followed hyphen or underscore, match 1 or more words characters (including underscores), hyphen or underscore, , 1 or more word characters in capture group. lastly, not match hyphen or underscore @ end of line."
the fact underscore (but not hyphen) word (\w
) character messes regex. in general, rather using \w
, might want use \p{alpha}
or \p{alnum}
(or posix [[:alpha:]]
or [[:alnum:]]
).
try this.
r = / (?<= # begin positive lookbehind [^_-] # match character other underscore or hyphen ) # end positive lookbehind ( # begin capture group 1 (?: # begin non-capture group -+ # match 1 or more hyphens | # or _+ # match 1 or more underscores ) # end non-capture group [^_-] # match character other underscore or hyphen ) # end capture group 1 /x # free-spacing regex definition mode '_cats_have--nine_lives--'.gsub(r) { |s| s[-1].upcase } #=> "_catshaveninelives--"
this regex conventionally written follows.
r = /(?<=[^_-])((?:-+|_+)[^_-])/
if letters lower case 1 alternatively write
'_cats_have--nine_lives--'.split(/(?<=[^_-])(?:_+|-+)(?=[^_-])/). map(&:capitalize).join #=> "_catshaveninelives--"
where
'_cats_have--nine_lives--'.split(/(?<=[^_-])(?:_+|-+)(?=[^_-])/) #=> ["_cats", "have", "nine", "lives--"]
(?=[^_-])
positive lookahead requires characters on split made followed character other underscore or hyphen
Comments
Post a Comment