VIM - Replace based on a search regex - regex

I've got a file with several (1000+) records like :
lbc3.*'
ssa2.*'
lie1.*'
sld0.*'
ssdasd.*'
I can find them all by :
/s[w|l].*[0-9].*$
What i want to do is to replace the final part of each pattern found with \.*'
I can't do :%s//s[w|l].*[0-9].*$/\\\\\.\*' because it'll replace all the string, and what i need is only replace the end of it from
.'
to
\.'
So the file output is llike :
lbc3\\.*'
ssa2\\.*'
lie1\\.*'
sld0\\.*'
ssdasd\\.*'
Thanks.

In general, the solution is to use a capture. Put \(...\) around the part of the regex that matches what you want to keep, and use \1 to include whatever matched that part of the regex in the replacement string:
s/\(s[w|l].*[0-9].*\)\.\*'$/\1\\.*'/
Since you're really just inserting a backslash between two strings that you aren't changing, you could use a second set of parens and \2 for the second one:
s/\(s[w|l].*[0-9].*\)\(\.\*'\)$/\1\\\2/
Alternatively, you could use \zs and \ze to delimit just the part of the string you want to replace:
s/s[w|l].*p0-9].*\zs\ze\*\'$/\\/

Related

Finding the string or substring within nth occurrence in a line

I would like to find the third occurrence of string inside quotes in order to replace this string or part of this string. This is a typical line I have to deal with:
"/activities/absenceactivity/lang/#LANG_ID#/prop_dialog.php";"BA2_PD_SCR";"Opis
dogodka";"Event description";"Descrição do Evento";"ÐпиÑ
подÑÑ";"";"č®vykio aprašymas";"Descripción del evento";"";
I know that "([^"]*)" shows every occurrence of text and quotes but I would like to get just the third one, in this example "Opis dogodka" in order to perform Search & Replace in Sublime Text.
Problem is to find the third occurrence of string within the quotes, replace it entirely or just partially and make sure that the Regex provides also a solution for an empty
""
strings.
Thank you.
I'm sure there are ways to simplify this further, but if you're ok with brute force:
Sublime command:
Find: "[^"]*";"[^"]*";"([^"]*)".*
Replace: $1
NP++:
Find what: "([^"]*)";"([^"]*)";"([^"]*)".*
Replace with: $3
sed:
sed 's/"\([^"]*\)";"\([^"]*\)";"\([^"]*\)".*/\3/'
You can use {} pattern repetition:
/(?:"([^"]*)";){3}/ # first match group will be 'Opis dogodka'
Demo
Or, use a global type match and then take the third match. This might require logic such as slicing or looping:
/"([^"]*)";/g
Demo 2
Or, just manually put in the first two patterns to skip:
/^"[^"]*";"[^"]*";("[^"]*";)/
Demo 3
Or combine repetition to skip the first n-1 then capture the nth match:
/^(?:"[^"]*";){2}("[^"]*";)/
Demo 4

Remove columns from CSV

I don't know anything about Notepad++ Regex.
This is the data I have in my CSV:
6454345|User1-2ds3|62562012032|324|148|9c1fe63ccd3ab234892beaf71f022be2e06b6cd1
3305611|User2-42g563dgsdbf|22023001345|0|0|c36dedfa12634e33ca8bc0ef4703c92b73d9c433
8749412|User3-9|xgs|f|98906504456|1534|51564|411b0fdf54fe29745897288c6ad699f7be30f389
How can I use a Regex to remove the 5th and 6th column? The numbers in the 5th and 6th column are variable in length.
Another problem is the User row can also contain a |, to make it even worse.
I can use a macro to fix this, but the file is a few millions lines long.
This is the final result I want to achieve:
6454345|User1-2ds3|62562012032|9c1fe63ccd3ab234892beaf71f022be2e06b6cd1
3305611|User2-42g563dgsdbf|22023001345|c36dedfa12634e33ca8bc0ef4703c92b73d9c433
8749412|User3-9|xgs|f|98906504456|411b0fdf54fe29745897288c6ad699f7be30f389
I am open for suggestions on how to do this with another program, command line utility, either Linux or Windows.
Match \|[^|]+\|[^|]+(\|[^|]+$)
Repalce $1
Basically, Anchor to the end of the line, and remove columns [-1] and [-2] (I assume columns can't be empty. Replace + with * if they can)
If you need finer detail then that, I'd recommend writing a Java or Python script to manual parse and rewrite the file for you.
I've captured three groups and given them names. If you use a replace utility like sed or vimregex, you can replace remove with nothing. Or you can use a programming language to concatenate keep_before and keep_after for the desired result.
^(?<keep_before>(?:[^|]+\|){3})(?<remove>(?:[^|]+\|){2})(?<keep_after>.*)$
You may have to remove the group namings and use \1 etc. instead, depending on what environment you use.
Demo
From Notepad++ hit ctrl + h then enter the following in the dialog:
Find what: \|\d+\|\d+(\|[0-9a-z]+)$
Replace with: $1
Search mode: Regular Expression
Click replace and done.
Regex Explain:
\|\d+ : match 1st string that starts with | followed by number
\|\d+ : match 2nd string that starts with | followed by number
(\|[0-9a-z]+): match and capture the string after the 2nd number.
$ : This is will force regex search to match the end of the string.
Replacement:
$1 : replace the found string with whatever we have between the captured group which is whatever we have between the parentheses (\|[0-9a-z]+)

atom - How to replace in Atom without replacing some part of the search?

Let's say I have these lines in a file:
This and an child
That and a entrepreneur
These and a banana
This and an cookie
And I want to replace all an and a that are incorrect.
I can use an [^aeiou] or a ^[aeiou] to find all the incorrects (I think, I'm not good with regexp).
What I want is to replace the incorrects using these expressions without changing the letter after the a/an.
How can I do that?
You need to use a capturing group, (...), and then include that in the replacement
Search:
an ([^aeiou])
a ([aeiou])
Replace:
a $1
an $1

Regexp to search and replace with transformed result

In our project we had translations called like
Resources.Blabla.MooFoo.GetString("I am a whatever string!");
It was using Resgen, and now we want to use "standard" way for it.
We parsed out the source text files(removing special chars from keys) into resx files, and now want to search-replace whole project to change every call to
Resources.Translate("Iamawhateverstring");
The point here is that aside from replacing the call signature, which is not a problem, I need to parse out symbols like spaces, dots, etc. from parameter so that
"I am a whatever string!"
turns into
"Iamawhateverstring"
How can I do it ?
Regex for spaces replacement:
(?<=(GetString\(")[A-Za-z0-9 ]+) (?=(.*?("\)){1}))
(?<=(GetString\(")[A-Za-z0-9 ]+) looks before space character for GetString("[a-Z0-9] including space if there is one or more space occurance in string
(?=(.*?("\)){1})) looks after space character for ")
I would replace it using this regex: DEMO
(Resources.Blabla.MooFoo.GetString)(\(".*"\);)
then when you get the capture groups:
Replace capture group 1 with "Resources.Translate"
Replace capture group 2 using captureGroup2.replace(/\s/g, '')
So essentially it is a two step process.

Notepad++ and delimiters: automatically replace ``string'' by \command{string}

Within Notepad++, I want to replace many instances of the type ``string'' by \command{string} where string can be any string of characters. I am fairly close to what I want to achieve with:
Find: (?<=``)(.*?)(?='')
Replace: \\command{\1}
There is still a problem. With the regex code above, instead of \command{string} I get ``\command{string}'' and I am not sure why the `` and '' are not removed?
It is because you are using lookaround assertions. Lookaround (zero-width) assertions only assert that a position can be matched and do not "consume" any characters on the string. You can use the below regular expression.
Find: ``([^']+)''
Replace: \\command{\1}
You need to wrap everything into a capture group and use that. NP++ seems to not support lookahead/behind, but you dont need that for this specific case anyway:
``([^']+)'' -> \\command{\1}
This will make sure it does not match two commands (longest match) in something like:
run ``ls -l'' or ``ls -a''