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