Ruby regex - gsub only captured group

后端 未结 6 776
夕颜
夕颜 2021-01-03 22:47

I\'m not quite sure I understand how non-capturing groups work. I am looking for a regex to produce this result: 5.214. I thought the regex below would work, bu

相关标签:
6条回答
  • 2021-01-03 22:53

    gsub replaces the entire match the regular expression engine produces. Both capturing/non-capturing group constructs are not retained. However, you could use lookaround assertions which do not "consume" any characters on the string.

    "5,214".gsub(/\d\K,(?=\d)/, '.')
    

    Explanation: The \K escape sequence resets the starting point of the reported match and any previously consumed characters are no longer included. That being said, we then look for and match the comma, and the Positive Lookahead asserts that a digit follows.

    0 讨论(0)
  • 2021-01-03 22:57

    non capturing groups still consumes the match
    use
    "5,214".gsub(/(\d+)(,)(\d+)/, '\1.\3')
    or
    "5,214".gsub(/(?<=\d+)(,)(?=\d+)/, '.')

    0 讨论(0)
  • 2021-01-03 23:00

    I know nothing about ruby.

    But from what i see in the tutorial

    gsub mean replace, the pattern should be /(?<=\d+),(?=\d+)/ just replace the comma with dot or, use capture /(\d+),(\d+)/ replace the string with "\1.\2"?

    0 讨论(0)
  • 2021-01-03 23:02

    It is also possible to use Regexp.last_match (also available via $~) in the block version to get access to the full MatchData:

    "5,214".gsub(/(\d),(\d)/) { |_|
        match = Regexp.last_match
    
        "#{match[1]}.#{match[2]}"
    }
    

    This scales better to more involved use-cases.

    Nota bene, from the Ruby docs:

    the ::last_match is local to the thread and method scope of the method that did the pattern match.

    0 讨论(0)
  • 2021-01-03 23:06

    You don't need regexp to achieve what you need:

    '1,200.00'.tr('.','!').tr(',','.').tr('!', ',')

    • Periods become bangs (1,200!00)
    • Commas become periods (1.200!00)
    • Bangs become commas (1.200,00)
    0 讨论(0)
  • 2021-01-03 23:07

    You can't. gsub replaces the entire match; it does not do anything with the captured groups. It will not make any difference whether the groups are captured or not.

    In order to achieve the result, you need to use lookbehind and lookahead.

    "5,214".gsub(/(?<=\d),(?=\d)/, '.')
    
    0 讨论(0)
提交回复
热议问题