开发者

How to keep same substrings in vim regex

I'd ideally like a vim answer to this:

I want to change

[*, 1, *, *] to [*, 2, *, *]

Here the stars refer to individual characters in the substring, which I would like to keep unchanged. For example

[0, 1, 0, 1] to [0, 2, 0, 1]
[1, 1, 1, 1] to [1, 2, 1, 1]

If people know how t开发者_开发技巧o do this in perl or python or whatever, that would be equally good. Cheers


This works :)

1,$s/\[\(\d\+\),\s\+\d\+,\s\+\(\d\+\),\s\+\(\d\+\)\]/[\1, 2, \2, \3]/g

or

%s/\[\(\d\+\),\s\+\d\+,\s\+\(\d\+\),\s\+\(\d\+\)\]/[\1, 2, \2, \3]/


The following should do what you want:

:%s/\(\[[^,]*, *\)\(\d\)\([^]]*\]\)/\=submatch(1) . (submatch(2)+1) . submatch(3)/

In Vim, that is.


If those are strings in Python

>>> a = "[0, 1, 0, 1]"
>>> b = a[:4] + '2' + a[5:]
>>> b
'[0, 2, 0, 1]'

Lists are a little more trivial:

>>> c = [0, 1, 0, 1]
>>> c[1] = 2
>>> c
[0, 2, 0, 1]
>>>


This one is shorter and a little more general purpose.

:%s/\(\[[^,],\s*\)1,/\12,/

The pattern doesn't care what is in the first slot of the list, and doesn't look at the rest of the list. This may be better, or worse, depending on what exactly you're trying to do.


Note while using regexes for substitutions/modifications it is important to focus around the portion of the string you want to modify. Here is a short regex to do what you want (in perl), that illustrates this idea with your data.

Assuming $line contains the line you want to modify

 my $two=2;  
 $line =~ s/(,\s+)\d+/\1$two/;

The regex looks for the first comma, matches that and a arbitary number of spaces following the comma. This is remembered in the first back reference. After that it matches a arbitary number of digits. Finally it replaces what was matched by the string in the first backreference followed by 2. Applying this on your sample data gives
[0, 1, 0, 1] becomes [0, 2, 0, 1]
[1, 1, 1, 1] becomes [1, 2, 1, 1]

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜