0

I have this string:

b'32^"Strings" c32 d32 c32 b32 r8. \break

I want to replace [a-z] (except r) with r and remove ' everywhere outside "..". I want to ignore \break.

Final output should be:

r32^"Strings" r32 r32 r32 r32 r8. \break

The tricky part is sometimes the ".." and/or \break may not be present.

For example:

b'32 c32 d32 c32 b32 a32 g32 fis32 d'32 \break

Should be converted to:

r32 r32 r32 r32 r32 r32 r32 r32 r32 \break

A single command would be desirable, but multiple commands are acceptable too.

I tried:

s/^\(.\{-}\)\ze".*$/\=substitute(submatch(1), "[a-z']", 'r', 'g')/

and

s/^.*"\zs\(.*\)/\=substitute(submatch(1), "[a-z]", "r", "g")/

But I am not sure how to handle optional ".." and \break.

1 Answer 1

2

I would propose you:

s/\v(<[a-z]'?|"[^"]*"|\\\w+)/\=submatch(1)[0]=='"'||submatch(1)[0]=='\'?submatch(1):'r'/g

The idea is to match by token either:

  • starting with a letter and an optional quote: [a-z]'?
  • a quoted string: "[^"]*"
  • a back-slashed word: \\\w+

Then to decide to make the replacement by r only on the first case.

i.e.: if the token is not a string or a back-slashed word (submatch(1)[0]=='"'||submatch(1)[0]=='\')

Remark: the leading \v allow to clarify the expression avoiding to have to escape the special characters: <, (, ), |, ?, + ([, ] and * don't need to be escaped).

1
  • 2
    Make sure to add the g flag to the end of the command
    – Wilson
    Jan 27, 2023 at 3:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.