32

I have something akin to <Foobar Name='Hello There'/> and need to change the single quotation marks to double quotation marks. I tried :s/\'.*\'/\"\0\" but it ended up producing <Foobar Name="'Hello There'"/>. Replacing the \0 with \1 only produced a blank string inside the double quotes - is there some special syntax I'm missing that I need to make only the found string ("Hello There") inside the quotation marks assign to \1?

Nick Knowlson
  • 7,185
  • 6
  • 47
  • 63
ravuya
  • 8,586
  • 4
  • 30
  • 33

9 Answers9

73

There's also surround.vim, if you're looking to do this fairly often. You'd use cs'" to change surrounding quotes.

kejadlen
  • 1,519
  • 1
  • 10
  • 10
  • is there a way to map this to some leader command? I can't get to do it :\ – Fuad Saud Jan 17 '14 at 08:26
  • You shouldn't need to map this to a leader command, since it's using a custom `cs` motion with two arguments - `'` as the target, and `"` as the replacement. – kejadlen Jan 30 '14 at 20:02
23

You need to use groupings:

:s/\'\(.*\)\'/\"\1\"

This way argument 1 (ie, \1) will correspond to whatever is delimited by \( and \).

rui
  • 11,015
  • 7
  • 46
  • 64
22

%s/'\([^']*\)'/"\1"/g

You will want to use [^']* instead of .* otherwise

'apples' are 'red' would get converted to "apples' are 'red"

rayd09
  • 1,837
  • 17
  • 20
9

unless i'm missing something, wouldn't s/\'/"/g work?

tosh
  • 305
  • 1
  • 5
  • That was my compromise, but I felt that it wasn't quite right, especially if there were a single quote inside the attribute. I don't think that can happen in XML, but it might happen in some other situation down the road that needs this same solution. – ravuya Jan 20 '10 at 17:59
  • A single quote inside a single-quoted attribute should be `'` and a double quote inside a double-quoted attribute should be `"`. Of course a single quote might live inside a double-quoted attribute and vice versa... – ephemient Jan 20 '10 at 18:44
8

Just an FYI - to replace all double quotes with single, this is the correct regexp - based on rayd09's example above

:%s/"\([^"]*\)"/'\1'/g
BandsOnABudget
  • 3,966
  • 2
  • 17
  • 19
2

You need to put round brackets around the part of the expression you wish to capture.

s/\'\(.*\)\'/"\1"/

But, you might have problems with unintentional matching. Might you be able to simply replace any single quotes with double quotes in your file?

martin clayton
  • 76,436
  • 32
  • 213
  • 198
1

You've got the right idea -- you want to have "\1" as your replace clause, but you need to put the "Hello There" part in capture group 1 first (0 is the entire match). Try:

:%/'\(.*\)'/"\1"

1

Shift + V to enter visual block mode. Highlight the lines of code you want to remove single quotes from.

Then hit : on keyboard

Then type

s/'//g

Press Enter.

Done. You win.

0

Presuming you want to do this on an entire file ...

N Mode:

ggvG$ [SHIFT+:]  

X Mode:

'<,'>/'/" [RET]
sth
  • 222,467
  • 53
  • 283
  • 367
Edward J Beckett
  • 5,061
  • 1
  • 41
  • 41