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]
精彩评论