Home > Software design >  Ruby regex replace text, except text inside delimiter
Ruby regex replace text, except text inside delimiter

Time:08-07

I would like to use Ruby's gsub to replace text except those inside a specific delimiter, like this:

regex = /(. ?)(@. ?@)(. ?)/
text = "aaa@xxx@bbb aaa@xxx@bbb"
text.gsub(regex){"#{$1.upcase}#{$2}#{$3.upcase}"}

I would like the return value to be AAA@xxx@BBB AAA@xxx@BBB, but it is AAA@xxx@BBB AAA@xxx@Bbb.

CodePudding user response:

Try:

regex = /(?:@.*?@|@|\G)\K[^@] /
text = "aaa@xxx@bbb aaa@bbb"
puts text.gsub(regex, &:upcase)

Prints:

AAA@xxx@BBB AAA@BBB

See an online demo


  • (?:@.*?@|@|\G) - Non-capture group to match either @ to the nearest @ or a single @ or match at the end of previous reported match;
  • \K[^@] - Reset match and then capture 1 characters other than @.

CodePudding user response:

If you want to uppercase the left and right side after the @ chars:

([^\s@] )((?:@[^\s@] )*@)([^\s@] )

The pattern matches:

  • ([^\s@] ) Capture group 1, match 1 chars other than @ or a whitespace char
  • ( Capture group 2
    • (?:@[^\s@] )*@ Optionally repeat matching @ followed by 1 chars other than @, and then match at least a single @
  • ) Close group 2
  • ([^\s@] ) Capture group 3, match 1 chars other than @ or a whitespace char

Regex demo | Ruby demo

regex = /([^\s@] )((?:@[^\s@] )*@)([^\s@] )/
text = "aaa@xxx@bbb aaa@xxx@bbb aaa@bbb aaa@xxx@xxx@xxx@bbb"

puts(text.gsub(regex){"#{$1.upcase}#{$2}#{$3.upcase}"})

Output

AAA@xxx@BBB AAA@xxx@BBB AAA@BBB AAA@xxx@xxx@xxx@BBB

If you als want to match whitespace chars and newlines in between:

([^@] )((?:@[^@] )*@)([^@] )

CodePudding user response:

Does this resolve your question? If @ is the separator, then IMHO, splitting and uppercasing if even index in array would print the expected outcome.

text = "aaa@xxx@bbb aaa@xxx@bbb"
sArray = text.split(/@/)

finalText = ""

# for loop on sArray with index
sArray.each_with_index do |s, i|
    # if index is odd
    if i.even?
        finalText  = s.upcase
    else
        finalText  = s.downcase
    end
end

puts finalText
# AAAxxxBBB AAAxxxBBB
  • Related