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

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -