vim search and replace between number - vim

I have a pattern where there are double-quotes between numbers in a CSV file.
I can search for the pattern by [0-9]\"[0-9], but how do I retain value while removing the double quote. CSV format is like this:
"1234"5678","Text1","Text2"
"987654321","Text3","text4"
"7812891"3","Text5","Text6"
As you may notice there are double quotes between some numbers which I want to remove.
I have tried the following way, which is incorrect:
:%s/[0-9]\"[0-9]/[0-9][0-9]/g
Is it possible to execute a command at every search pattern, maybe go one character forward and delete it. How can "lx" be embedded in search and replace.

You need to capture groups. Try:
:%s/\(\d\)"\(\d\)/\1\2/g
[A digit can also be denoted by \d.]

I know that this question has been answered already, but here's another approach:
:%s/\d\zs"\ze\d
Explanation:
%s   Substitute for the whole buffer
\d   look up for a digit
\zs set the start of match here
"     look up for a double-quote
\ze set the end of match here
\d   look up for a digit
That makes the substitute command to match only the double-quote surrounded by digits.
Omitting the replacement string just deletes the match.

You need boundaries to use in regular expression.
Try this:
:%s/\([0-9]\)"\([0-9]\)/\1\2/g

A bit naive solution:
%s/^"/BEGINNING OF LINE QUOTE MARK/g
%s/\",\"/quote comma quote/g
%s/\"$/quota end of line/g
%s/\"//g
%s/quota end of line/"/g
%s/quote comma quote/","/g
%s/BEGINNING OF LINE QUOTE MARK/"/g
A macro can be created quite easy out of it and invoked as many times as needed.

Related

Find and replace '\' in vim [duplicate]

For instance, if I wanted to a find and replace with strings containing backward or forward slashes, how would this be accomplished in vim?
Examples
Find & Replace is: :%s/foo/bar/g
what if I wanted to find all occurrences of <dog/> and replace it with <cat\>
Same way you escape characters most anywhere else in linuxy programs, with a backslash:
:%s/<dog\/>/<cat\\>
But note that you can select a different delimiter instead:
:%s#<doc/>#<cat\\>#
This saves you all typing all those time-consuming, confusing backslashes in patterns with a ton of slashes.
From the documentation:
Instead of the / which surrounds the pattern and replacement string, you
can use any other single-byte character, but not an alphanumeric character,
\, " or |. This is useful if you want to include a / in the search
pattern or replacement string.
%s:<dog/>:<cat>
You can replace the / delimiters if they become annoying for certain patterns.
Quote them with a backslash. Also, it often helps to use another delimiter besides slash.
:%s#<dog/>#<cat\\>#
or if you have to use slash as the substitute command delimiter
:%s/<dog\/>/<cat\\>/
I was looking for something similar, to search for register values containing the / character (to record a macro). The solution was to search using the ? token instead of the /.
The syntax is:
:%s/<dog\/>/<cat\\>/g
backslash slash backslash star
/(<- the prompt)\/\*
so after you type it looks like
/\/\*

How to create a line break after each 3 characters in one long line?

I want to break the below line into 1000 ones by 3 letters each:
saahaalaasabaaboabsabyaceactaddadoadsadzaffaftagaageagoagsahaahiahsaidailaimainairaisaitalaalbaleallalpalsaltamaamiampamuanaandaneaniantanyapeapoappaptarbarcarearfarkarmarsartashaskaspassateattaukavaaveavoawaaweawlawnaxeayeaysazobaabadbagbahbalbambanbapbarbasbatbaybedbeebegbelbenbesbetbeybibbidbigbinbiobisbitbizboabobbodbogboobopbosbotbowboxboybrabrobrrbubbudbugbumbunburbusbutbuybyebyscabcadcamcancapcarcatcawcayceecelcepchicigciscobcodcogcolconcoocopcorcoscotcowcoxcoycozcrucrycubcudcuecumcupcurcutcwmdabdaddagdahdakdaldamdandapdawdaydebdeedefdeldendevdewdexdeydibdiddiedifdigdimdindipdisditdocdoedogdoldomdondordosdotdowdrydubdudduedugduhduidunduodupdyeeareateauebbecuedhedseekeeleffefsefteggegoekeeldelfelkellelmelsemeemsemuendengenseoneraereergernerrersessetaetheveeweeyefabfadfagfanfarfasfatfaxfayfedfeefehfemfenferfesfetfeufewfeyfezfibfidfiefigfilfinfirfitfixfizfluflyfobfoefogfohfonfopforfoufoxfoyfrofryfubfudfugfunfurgabgadgaegaggalgamgangapgargasgatgaygedgeegelgemgengetgeyghigibgidgiegiggingipgitgnugoagobgodgoogorgosgotgoxgoygulgumgungutguvguygymgyphadhaehaghahhajhamhaohaphashathawhayhehhemhenhepherheshethewhexheyhichidhiehimhinhiphishithmmhobhodhoehoghonhophoshothowhoyhubhuehughuhhumhunhuphuthypiceichickicyidsiffifsiggilkillimpinkinninsionireirkismitsivyjabjagjamjarjawjayjeejetjeujewjibjigjinjobjoejogjotjowjoyjugjunjusjutkabkaekafkaskatkaykeakefkegkenkepkexkeykhikidkifkinkipkirkiskitkoakobkoikopkorkoskuekyelablacladlaglamlaplarlaslatlavlawlaxlaylealedleelegleileklesletleulevlexleylezliblidlielinliplislitlobloglooloplotlowloxluglumluvluxlyemacmadmaemagmanmapmarmasmatmawmaxmaymedmegmelmemmenmetmewmhomibmicmidmigmilmimmirmismixmoamobmocmodmogmolmommonmoomopmormosmotmowmudmugmummunmusmutmycnabnaenagnahnamnannapnawnaynebneenegnetnewnibnilnimnipnitnixnobnodnognohnomnoonornosnotnownthnubnunnusnutoafoakoaroatobaobeobiocaodaoddodeodsoesoffoftohmohoohsoilokaokeoldoleomsoneonoonsoohootopeopsoptoraorborcoreorsortoseoudouroutovaoweowlownoxooxypacpadpahpalpampanpapparpaspatpawpaxpaypeapecpedpeepegpehpenpepperpespetpewphiphtpiapicpiepigpinpippispitpiupixplypodpohpoipolpompoopoppotpowpoxproprypsipstpubpudpugpulpunpuppurpusputpyapyepyxqatqisquaradragrahrairajramranraprasratrawraxrayrebrecredreerefregreiremrepresretrevrexrhoriaribridrifrigrimrinriprobrocrodroeromrotrowrubruerugrumrunrutryaryesabsacsadsaesagsalsapsatsausawsaxsayseasecseesegseiselsensersetsewsexshasheshhshysibsicsimsinsipsirsissitsixskaskiskyslysobsodsolsomsonsopsossotsousowsoxsoyspaspysristysubsuesuksumsunsupsuqsyntabtadtaetagtajtamtantaotaptartastattautavtawtaxteatedteetegteltentettewthethothytictietiltintiptistittodtoetogtomtontootoptortottowtoytrytsktubtugtuituntuptuttuxtwatwotyeudoughukeuluummumpunsupoupsurburdurnurpuseutauteutsvacvanvarvasvatvauvavvawveevegvetvexviavidvievigvimvisvoevowvoxvugvumwabwadwaewagwanwapwarwaswatwawwaxwaywebwedweewenwetwhawhowhywigwinwiswitwizwoewogwokwonwoowopwoswotwowwrywudwyewynxisyagyahyakyamyapyaryawyayyeayehyenyepyesyetyewyidyinyipyobyodyokyomyonyouyowyukyumyupzagzapzaszaxzedzeezekzepzigzinzipzitzoazoozuzzzz
Please advise me on how to approach it.
Try the following find and replace, in regex mode:
Find: (...)(?=.)
Replace: $1\r\n
Demo
The pattern (...)(?=.) matches and captures any three letters at a time. Then, we replace with those three letters ($1) followed by a break (I used \r\n, the Windows line ending; use \n if you are on Linux). Note that the pattern also only matches if the three letters found are not the final three letters in the string. The positive lookahead (?=.) avoids adding an unwanted break at the end.
This regular expression,
.{3}\K
with a replacement of:
\n
might simply do that.
The expression is explained on the top right panel of this demo if you wish to explore/simplify/modify it.

Substitute and change case for program variables

I'm changing some notation in a few source code files.
In particular, variable names using the format
m_variable1
m_anothervariable
should be renamed and reformatted to
mVariable1
mAnotherVariable
That is, substitute m_ with m and make the next character uppercase.
I know how todo simple substitutions, like
%s/m_/m/gc
using vim, but not sure how to add syntax for changing a char to uppercase in a substitute statement?
You can make the first character of variable name uppercase, but I think you can hardly separate words from a consecutive string simply by built-in command.
I hope following command will help you:
:%s/\vm_(\w+)/m\u\1/g
Explaination
\v enables the 'very magic' mode
\u makes the first character of word after it uppercase
\1 references the first captured group
Result
mVariable1
mAnothervariable

Substitute `number` with `(number)` in multiple lines

I am a beginner at Vim and I've been reading about substitution but I haven't found an answer to this question.
Let's say I have some numbers in a file like so:
1
2
3
And I want to get:
(1)
(2)
(3)
I think the command should resemble something like :s:\d\+:........ Also, what's the difference between :s/foo/bar and :s:foo:bar ?
Thanks
Here is an alternative, slightly less verbose, solution:
:%s/^\d\+/(&)
Explanation:
^ anchors the pattern to the beginning of the line
\d is the atom that covers 0123456789
\+ matches one or more of the preceding item
& is a shorthand for \0, the whole match
Let me address those in reverse.
First: there's no difference between :s/foo/bar and :s:foo:bar; whatever delimiter you use after the s, vim will expect you to use from then on. This can be nice if you have a substitution involving lots of slashes, for instance.
For the first: to do this to the first number on the current line (assuming no commas, decimal places, etc), you could do
:s:\(\d\+\):(\1)
The \(...\) doesn't change what is matched - rather, it tells vim to remember whatever matched what is inside, and store it. The first \(...\) is stored in \1, the second in \2, etc. So, when you do the replacement, you can reference \1 to get the number back.
If you want to change ALL numbers on the current line, change it to
:s:\(\d\+\):(\1):g
If you want to change ALL numbers on ALL lines, change it to
:%s:\(\d\+\):(\1):g
You can do what you want with:
:%s/\([0-9]\)/(\1)/
%s means global search and replace, that is do the search/replace for every line in the file. the \( \) defines a group, which in turn is referenced by \1. So the above search and replace, finds all lines with a single digit ([0-9]), and replaces it with the matched digit surrounded by parentheses.

Replacing quote marks around strings in Vim?

I have something akin to <Foobar Name='Hello There'/> and need to change the single quotation marks to double quotation marks. I tried :s/\'.*\'/\"\0\" but it ended up producing <Foobar Name="'Hello There'"/>. Replacing the \0 with \1 only produced a blank string inside the double quotes - is there some special syntax I'm missing that I need to make only the found string ("Hello There") inside the quotation marks assign to \1?
There's also surround.vim, if you're looking to do this fairly often. You'd use cs'" to change surrounding quotes.
You need to use groupings:
:s/\'\(.*\)\'/\"\1\"
This way argument 1 (ie, \1) will correspond to whatever is delimited by \( and \).
%s/'\([^']*\)'/"\1"/g
You will want to use [^']* instead of .* otherwise
'apples' are 'red' would get converted to "apples' are 'red"
unless i'm missing something, wouldn't s/\'/"/g work?
Just an FYI - to replace all double quotes with single, this is the correct regexp - based on rayd09's example above
:%s/"\([^"]*\)"/'\1'/g
You need to put round brackets around the part of the expression you wish to capture.
s/\'\(.*\)\'/"\1"/
But, you might have problems with unintentional matching. Might you be able to simply replace any single quotes with double quotes in your file?
You've got the right idea -- you want to have "\1" as your replace clause, but you need to put the "Hello There" part in capture group 1 first (0 is the entire match). Try:
:%/'\(.*\)'/"\1"
Shift + V to enter visual block mode. Highlight the lines of code you want to remove single quotes from.
Then hit : on keyboard
Then type
s/'//g
Press Enter.
Done. You win.
Presuming you want to do this on an entire file ...
N Mode:
ggvG$ [SHIFT+:]
X Mode:
'<,'>/'/" [RET]

Resources