Find pattern and replace with everything after pattern vim - regex

I have a file which has contents like so:
size is X1 Identifier is Y1
size is X1 Identifier is Y1
size is X1 Identifier is Y1
I want to re-arrage the file so that I get
Identifier is Y1 size is X1
Identifier is Y1 size is X1
Identifier is Y1 size is X1
How do I do this using vim find & replace? Or any other function in vim?

Use capturing groups and switch both groups
%s/\v(.*) (I.*)/\2 \1

As you say "Or any other function in vim", I'll offer an alternative by recording a macro. Personally I like using macros for things like this because you perform the action you want to do once, which helps you to think through exactly what you want, then just repeat the same thing as many times as you need to.
There's almost certainly a more efficient way than the below, but hopefully this is a fairly straightforward way.
Start with your cursor anywhere in the first line.
qa (start recording a macro in register a - you can substitute the a for any other letter)
0 (move to the start of the line)
Next, perform whatever command you want to use to remove the first part of the line, for example: 3dw - if you need more complex rules to identify the part of the line to move, this is where you would do it.
$ (move to the end of the line)
aSPACEESCp (append a space at the end of the line, then paste the text we deleted previously)
j (move down a line, so we're in the next line when we finish this run of the macro)
q (stop recording)
Once you've completed this, the first line should be in the state that you want it, and your cursor will be in the second line. To repeat the above starting from your current position, just do:
#a (or whatever letter you chose in the first step in place of the a).

I don't use vim that much, but the term you are searching for is "regex capture groups" which exist in nearly every regex implementation.
Capture groups give you the parts of a matched pattern and let you reorganize them to your needs.
Here is a question which might contain your answer:
Similar question

:%s/\(size is \w*\) \(Identifier is \w*\)/\2 \1/g
This works. I assumed that what you marked as X1, Y1 can be any word, hence \w*.

Related

vim delete till one character before the end of the line

I can press $ to go to the end of the line so if I want to delete everything till EOL I can do d$ (or D). What if I want to delete till EOL column - 1 character (or - n chars more broadly)?
Example
I have a row 1234.567890 where . represents the cursor and want 1234.0 (. represents cursor again).
How about
d/.$<CR>
This deletes until one character before EOL.
If there's no identical character in between (or the number of those is easily determined), the f and t commands are very useful, because they just involve two keystrokes (the command and the target character, possibly prepended by a [count]), and (unlike the more generic /...<CR>) they are limited to the current line. For your example, that would be dt0 then.
For more complex scenarios, before I stop and lengthily contemplate possible solutions, visual mode is a quick alternative that lets you iteratively fine-tune the area before applying the command. I think it's a great pragmatic addition to the original command set of vi. For your example, that would be v$hd.
There is no built-in movement for that, but you can create
your own easily with :omap. It will work with any
operator.
:onoremap <silent> q :<C-U>normal! v$hh<CR>
Now dq will do what you want, as well as cq to change
until the before-last char, vq, yq and so on.
This works by replacing q with a call to :normal to
initiate a visual selection, up to the end of the line
(v$) and back two characters (that's because $ selects
until the newline itself). The <C-U> clears any possible
range.

Eclipse, regex search and replace

I have a file which contains text like:
1x
2x
5x
10x
50x
100x
.....
Using Eclipse search and replace with regex, how do I script to have an output like
x1
x2
x5
x10
x50
x100
...
That is to say, search for a regex, break it into fields (\d+x, thus \d+ and 'x' in my case), and reuse the field elements later to resubstitute as 'x'+'\d+'.
I looked at a previous question on same lines, but I want to take that a step further.
Thank you.
Search for
(\d+)x
and replace with
x\1
And enable "Regular expressions". It will put the 'x' in front of the number.
search: (\d+)(.+)
replace with : \2\1
or $2$1 whichever eclipse supports

Insert a number of spaces in replacement

I have a long line of code that I need to split into separate lines:
Method(new Namespace::ClassName(LongParameterName1, LongParameterName1, LongParameterName3));
I want to split it the following way:
Method(new Namespace::ClassName(LongParameterName1,
LongParameterName1,
LongParameterName3));
The regular expression will be like this:
s:, :,\r :
How can I set a number of spaces that are used (if I can)?
NOTE: I have quite a big number of lines like this so that's why I want to use the regex.
You can calculate the position where you want to begin variable names in following lines and use a substitution command with expression, like:
:let c = strridx(getline('.'), '(')
:s/\v(,)/\=submatch(1) . "\r" . printf("%" . c . "s", " ")/g
I wrote them in two instructions to avoid a Markdown scroll, but you can join them with a pipe character.
First instruction searches the position of the last opening parentheses (the first one beginning from the end). And second instruction uses a printf() to insert that number of spaces after the newline character.
It yields:
Method(new Namespace::ClassName(LongParameterName1,
LongParameterName1,
LongParameterName3));
To repeat this task multiple times you can wrap these instructions in a function and call them from a :g command. I hope you get the idea.
That how I would do it:
set a macro (qa') that search for the next ',' (<escape>\,), hop into edit mode and hit enter (i<enter>), quit recording the macro (q)
replay that macro very quickly until I'm done with the line (#a then ##)
replace the cursor on the second line and start recording a new macro (qa'): I then press <space> until your parameter is sufficiently tabbed, and move to next line while replacing the cursor on the first caracter (<escape>j^), quit recording the macro (q)
and replay that final macro like the first one (#a then ##)
That looks less elegant than regexes, but IMHO, when it's time to get things done, well, it's time to get things done :)
I would use the regex first and then indent. For instance...
s:, :,\r:g
V?Method<cr><cr>8>
In real practice I'd probably use >....... instead of 8> because it lets you visualize how much you're indenting.

Vim: How to apply external command only to lines matching pattern

Two of my favorite Vim features are the ability to apply standard operators to lines matching a regex, and the ability to filter a selection or range of lines through an external command. But can these two ideas be combined?
For example, I have a text file that I use as a lab notebook, with notes from different dates separated by a line of dashes. I can do something like delete all the dash-lines with something like :% g/^-/d. But let's say I wanted to resize all the actual text lines, without touching those dash lines.
For a single paragraph, this would be something like {!}fmt. But how can this be applied to all the non-dash paragraphs? When I try what seems the logical thing, and just chain these two together with :% v/^-/!fmt, that doesn't work. (In fact, it seems to crash Vim...)
Is there a way to connect these two ideas, and only pass lines (not) matching a pattern into an external command like fmt?
Consider how the :global command works.
:global (and :v) make two passes through the buffer,
first marking each line that matches,
then executing the given command on the marked lines.
Thus if you can come up with a command – be it an Ex command or a command-line tool – and an associated range that can be applied to each matching line (and range), you have a winner.
For example, assuming that your text is soft-wrapped and your paragraphs are simply lines that don't begin with minus, here's how to reformat the paragraphs:
:v/^-/.!fmt -72
Here we used the range . "current line" and thus filtered every matching line through fmt. More complicated ranges work, too. For instance, if your text were hard-wrapped and paragraphs were defined as "from a line beginning with minus, up until the next blank line" you could instead use this:
:g/^-/.,'}!fmt -72
Help topics:
:h multi-repeat
:h :range!
:h :range
One way to do it may be applying the command to the lines matching the pattern 'not containing only dashes'
The solution I would try the is something like (not tested):
:g/\v^(-+)#!/normal V!fmt
EDIT I was doing some experiments and I think a recurvie macro should work for you
first of all set nowrapscan:
set nowrapscan
To prevent the recursive macro executing more than you want.
Then you make a search:
/\v^(-+)#!
Test if pressing n and p works with your pattern and tune it up if needed
After that, start recording the macro
qqn:.!awk '{print $2}'^M$
In this case I use awk as an example .! means filter current line with an external program
Then to make the macro recursive just append the string '#q' to the register #q
let #q .= '#q'
And move to the beggining of the buffer to apply the recursive macro and make the modifications:
gg#q
Then you are done. Hope this helps

How do I substitute selected contents despite any regex characters in vim?

In following code:
int return_int_func() { return 0; }
float fv = return_int_func();
Obviously, compiler will warn me fv may lost precisions because of auto-casting. Face lots of those things, I want replace all stuffs with substitute command. In short, I want this:
float fv = static_cast<float>(return_int_func());
But real codes has lots of forms like that:
float fv = obj.int_field;
float fv = obj->load_int_field("name");
float fv = xx.yy->zz;
I want select my target (obj.int_field,obj->load_int_field("name") or xx.yy->zz) and replace it with static_cast<float>(\1). I tried this:
:'<,'>s/\%V/static_cast<float>(&)/g
But vim replaces all characters in selected word with static_cast... and that isn't what I want at all. Then I tried this:
:'<,'>s/\(\%V\)/static_cast<float>(\1)/g
Vim also do the same thing. I have no idea how to replace whole content (and despite any regex characters) with my pattern. Any suggestions?
The solution is almost too easy! Here it is.
:s/\%V.*\%V./static_cast<float>(&)/
This is actually almost the same as the example from the :help. We can take away from this that we should all just have looked up :h /\%V first thing in the morning ...
\%V is a zero-width atom that matches stuff that is selected in Visual mode. Here it can match at the start of the Visual area. .* then matches (greedily) as much as it can; its greediness is reined in by the final \%V., which requires the last character of the match also to lie within the Visual area.
Tip: If you need to make this change many times over many lines, define the following mappings (even better: put them in your vimrc permanently).
nnoremap & :&&<CR>
xnoremap & :&&<CR>
Then you can repeat the substitution shown above by simply selecting something, and then pressing & to perform the substitution.
Let me try to paraphrase your question: You would like to Visual select some text, and then perform a substitution, where the selected text is also part of the replacement text.
I think in this case a macro is a much better tool.
To create the macro, first select the first piece of text that you want to wrap in the static cast. For example, select return_int_func(). (For each step, I'll show what the buffer looks like.)
When you're ready, press qq to start recording into register q, then press c.
float fv = |;
Type the left part of your wrapper text, static_cast<float>(.
float fv = static_cast<float>(|;
Press CTRL-R " (Control-R followed by "): this will reinsert the original text.
float fv = static_cast<float>(return_int_func()|;
Type ) to complete the change, and then Escape to leave insert mode.
float fv = static_cast<float>(return_int_func()▉;
Finally, press q to stop recording.
At this point you have made the first change and also recorded it as a macro in register q.
For all remaining changes, simply select a target such as obj->load_int_field("name") and press #q to repeat the change.
Look up :help 10.1 for more information about macros.
The \%V facility is really not for acting on the selected text as a whole; more for searching inside of that text.
Assuming that you are going to be putting this into a function or maybe mapping this to a key combination, here is an alternative approach that does what you are looking for:
:exec 'normal! gv"adistatic_cast<float>('|exec 'normal! "apa)'
Note that this will use your a buffer, so if you want to use another buffer you can change the two instances of "a with "x, where x is the buffer you wish to use.
Basically this is going to programmatically yank the selected text, insert static_cast<float>(, paste the text that was selected, and then insert ).
You can try
:%s/float fv =(.*)$/float fv = static_cast<float>(\1)/g
if I understood you right, you want to do text substitution only on selected text. This is not so easy to do, at least no so easy as a :s command can do. Because, your visual selection can be in single line, can cross multi lines, also it could char-wise, line-wise, block-wise..
but it can be done with this function:
function! SubVisualText(pat, repl,flag)
try
let v_save = #v
normal! gv"vy
let s = #v
let s = substitute(s, a:pat, a:repl,a:flag)
call setreg('v',s,visualmode())
normal! gv"vp
finally
let #v = v_save
endtry
endfunction
you use it by:
source the function
visual select the area (could be done by v, V or Ctrl-V)
:<ctrl-u>call SubVisualText(pattern, replacement, flag)<Enter>
the <ctrl-u> is for removing the leading range, since the function doesn't need the range.
when you run it, it looks like:(I just tested with Ctrl-V selection)