简体   繁体   中英

awk, sed or vim regex

I'm searching for the best way to add a string to an existing string while I don't want to replace the whole string.

self.fields_desc.append(BitField("foo", 0x3, 4))

sould be replaced by:

self.fields_desc.append(BitField("foo" + str(self.__class__.i), 0x3, 4))

Using which tool would allow me to do this with the less possible trouble? In vim I could do:

:%s/self.fields_desc.append(BitField("[a-zA-Z0-9]*", 0x[0-9]*, [0-9]*))/self.fields_desc.append(BitField("foo" + str(self.__class__.i), 0x3, 4))/g

But I don't know how I would tell vim to not replace the regex I wrote. Could you give me a hand on this please?

Use capturing groups (note the "\" before the "(" and ")", and the "\1", "\2" etc):

:%s/self\.fields_desc\.append(BitField(\("[a-zA-Z0-9]*"\), \(0x[0-9]\+\), \([0-9]\+\)))/self.fields_desc.append(BitField(\1 + str(self.__class__.i), \2, \3))/g

changes:

self.fields_desc.append(BitField("foo", 0x3, 4))
self.fields_desc.append(BitField("test", 0x5, 3))

to

self.fields_desc.append(BitField("foo" + str(self.__class__.i), 0x3, 4))
self.fields_desc.append(BitField("test" + str(self.__class__.i), 0x5, 3))

Note:

  1. I've escaped the ".", as "." matches any character (except newline), and you want a literal "." character.
  2. I've replaced * with + for the number matches: I doubt you want to match self.fields_desc.append(BitField("foo", 0x,) etc.
  3. If you aren't sure whether the spacing is correct, ie, you don't always have self.fields_desc.append(BitField("foo", 0x3... but sometimes self.fields_desc.append(BitField("foo",0x3 or self.fields_desc.append(BitField("foo", 0x3 , then add a * after the space characters. Although I'd suggest insteading standardising your code.

See Regex grouping and The regex "dot" .


As sidyll says, it is probably better to learn to use the built-in character classes "\d", "\w" (see Shorthand character classes ) and so on:

:%s/self\.fields_desc\.append(BitField(\("\w*"\), \(0x\d\+\), \(\d\+\)))/self.fields_desc.append(BitField(\1 + str(self.__class__.i), \2, \3))/g

This is both for brevity, and readability. Also, otherwise, readers will assume you have some special reason for defining your own character class (ie, they will read it twice to make sure there's not some unknown character in there).

Please please avoid unnecessary matches and replaces. Use built-in character classes. And escape those dots. There is no need to group things here.

:%s/self\.fields_desc\.append(BitField("\w*"\zs\ze, 0x\d, \d))/ + str(self.__class__.i)

You probably don't need the g flag, I doubt two of these will appear on the same line.

See :h \zs and :h \ze .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM