I have lines like this:
<prefix> <token1>, <token2>, .... <tokenN>;
where the number of tokens is variable and each token is a character or digit.
I would like to split them up in Vim like this:
<prefix> <token1>;
<prefix> <token2>;
...
<prefix> <tokenN>;
I tried grabbing the pattern like this /<prefix>\s\+\(\w\+,\s*\)\{1,}\(\w\+\);/
but i'm not sure how to extract the variable number of tokens (\1 and \2 only given tokenN-1 and tokenN).
Thoughts? Thanks in advance.
If your prefix is fixed everywhere (you suggested using a pattern starting with /<prefix>\s\+...
), then you can probably use something as simple as:
:g/^<prefix>\s/s/,\s\+/;\r<prefix> /g
In other words, for every line starting with <prefix>
, replace all commas (with following whitespace) with a semicolon, carriage return and the fixed <prefix>
followed by a space.
But assuming your <prefix>
is more complex and variable and you want to capture it in the regex:
One way to approach this with a :substitute
command is to use a further call to a substitute()
function as part of the replacement, which you can use to replace the arbitrary number of commas.
One possible approach is:
:s/\(\S\+\)\s\+[^,]*\zs\(,\s*[^,]*\)*\ze;$/\=substitute(submatch(0),',\s*',";\r".submatch(1)." ",'g')/
Breaking the pattern down:
\(\S\+\)
: Match the prefix in a capture group. (You can use something better, more specific than just non-blanks, to properly match only the lines you care about.)\s\+
: Skip whitespace.[^,]*
: Skip the first token.\zs
: Mark the start of the match. Substitution will only replace this part.\(,\s*[^,]*\)*
: Sequence of one or more tokens, preceded by a comma, and optional whitespace.\ze
: Mark the end of the match.;$
: Match the semicolon at the end of it all.At this point, the strategy is, again, to replace commas with semicolon, carriage return and prefix, but doing so dynamically.
That's achieved by using these in the replacement:
\=
: Use an expression in the replacement (see :help sub-replace-expression
.)substitute(submatch(0),',\s*',";\r".submatch(1)." ",'g')
: Replace commas (and optional whitespace following them) with a sequence of semicolon, carriage return and prefix, followed by a space.submatch(0)
: We're performing such replacement on the match (part in between the \zs
and \ze
only.)";\r"
: Beginning of the replacement, the semicolon and carriage return..
: The dot operator concatenates strings in Vimscript.submatch(1)
: Refers back to capture group 1, which we used in this case to capture the prefix.'g'
: Replace all matches.This is a fairly complex replacement, but has the advantage of taking care of the substitution in a single :s
command, which makes it easier to use it in a range or to later repeat it without having to record a macro.
The technique of using the substitute()
function in a :s
replacement is also an useful one to handle cases where capture groups are not enough, such as the one you present.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다