Exchanging words with regex in multiple lines - regex

I am using RegexBuddy software to change this:
Adam Sandler
Into this:
Sandler, Adam
Having very little knowledge about regex, I searched and found the command to solve this
([^_]+) (.+)
and to replace: $2, $1
It works. But there is a problem with multiple line. How can I make it work when the input is like this?
Adam Sandler
Rob Schneider
Ben Stiller
Now, output is like this:
Stiller, Adam Sandler
Rob Schneider
Ben

Use the following settings:
^$ Match at line breaks
Line by line

A perl equivalent,
sub revName{
my $fullname = "#_";
my ($lastname, $firstname);
if($fullname =~ /(\w+)\s+(\w+)/){
$firstname = $1;
$lastname = $2;
}
my $revname = "$lastname, $firstname";
return $revname;
}

Related

Regex list/column to comma delimited

I have a column of data, in this case captured from a website. I would like to convert this list into a comma separated list using regex either in the terminal or gedit, etc..
My list:
Liam
Noah
William
James
Oliver
Benjamin
What I want is:
Liam, Noah, William, James, Oliver, Benjamin
or
(Liam, Noah, William, James, Oliver, Benjamin)
or similar.
What I have tried is ^([A-Za-z]+)$("$1",) . I think it finds each name but it is not replacing anything.
It would also be great if something like this worked with numbers as well. Like,
10
20
30
pie
to
10,20,30,pie
Like this:
perl -i -pe 's/\n/, /' file
Output:
Liam, Noah, William, James, Oliver, Benjamin,
Or better:
perl -0ne 'my #a = (split /\n/, $_); print join (", ", #a) . "\n"' file
Output:
Liam, Noah, William, James, Oliver, Benjamin

Command to replace data in the nth column if the line begins with pattern

I have a file which looks like below:
16815966|Mr|Fit 5|Dont Usee|15-07-2015|||||||||||||0|2|0|0.00|0|
21875307|Mr|Father|Dont Remove|X|31-12-1899|||||||||||||0|118|0|0.00|0|
19180802|Mr|Dontye|Harr|01-01-1900|||||6666|Avenue||||||06-09-2013|0|26|2|396.00|1|
I Want to replace 4th column value with blank if begins with "Dont" and pattern like Dont Remove, Dont Use. But if its like one in 3rd example i wanna retain it.
Desired Result:
16815966|Mr|Fit 5||15-07-2015|||||||||||||0|2|0|0.00|0|
21875307|Mr|Father||X|31-12-1899|||||||||||||0|118|0|0.00|0|
19180802|Mr|Dontye|Harr|01-01-1900|||||6666|Avenue||||||06-09-2013|0|26|2|396.00|1|
Tried below and one with awk but no luck!!
sed '/^Dont/s/[^|]*//4'.
Following awk may help you in same.
awk -F"|" '$4~/^Dont/{$4=""} 1' OFS="|" Input_file
Output will be as follows.
16815966|Mr|Fit 5||15-07-2015|||||||||||||0|2|0|0.00|0|
21875307|Mr|Father||X|31-12-1899|||||||||||||0|118|0|0.00|0|
Solution for PHP.
Regex: (?m)^(?:[\w ]+\|){3}\K(?:(Dont))(?(1)[^\|]+) Substitution: "" empty string.
$text = '16815966|Mr|Fit 5|Dont Usee|15-07-2015|||||||||||||0|2|0|0.00|0|
21875307|Mr|Father|Dont Remove|X|31-12-1899|||||||||||||0|118|0|0.00|0|
19180802|Mr|Dontye|Harr|01-01-1900|||||6666|Avenue||||||06-09-2013|0|26|2|396.00|1|';
$text = preg_replace('/(?m)^(?:[\w ]+\|){3}\K(?:(Dont))(?(1)[^\|]+)/', "",$text);
print_r($text);
Output:
16815966|Mr|Fit 5||15-07-2015|||||||||||||0|2|0|0.00|0|
21875307|Mr|Father||X|31-12-1899|||||||||||||0|118|0|0.00|0|
19180802|Mr|Dontye|Harr|01-01-1900|||||6666|Avenue||||||06-09-2013|0|26|2|396.00|1|
Regex demo

Regex expression matching block of lines

I have this kind of file:
Analysis of its root cause:
Blablablablabla
blabablabkjhjk
kjbsqbdqbds
Details of the fix
blablabla
Analysis of its root cause:
fddsfsdfsdfdsfs
blnskdbbqbbb
xxxxggggggg
Details of the fix
blablabla
Analysis of its root cause is repeated x times in the file. I would like to get the block of text delimited by "Analysis of its root cause" and "Details of the fix".
Thanks a lot for your help.
I'm pretty sure there is some better way to do this, but that's what I could manage:
/(?(?<=Analysis of its root cause:\n)((.*\n)*)(?=Details of the fix\n))/gU
I'm using positive lookahead and lookbehind, and the following modifiers:
g - global - Don't return after first match
u - Ungreedy - Make quantifiers lazy
Try it online: https://regex101.com/r/xpz7pg/2
Not a regex answer, but using perl
Put your lines into a single file.
perl -e '$/="Analysis of its root cause:"; #Sets the record delimiter
while(<>){ #Iterates over the file, record by record
chomp; #Removes the delimiter
if ($_ =~ /\n(.*?)\nDetails of the fix\n(.*)\n/s){ #Matches strings between Details of the fix. . is allowed to match newline
print "ONE:$1TWO:$2"} # $1 is the analysis, $2 is the details
}'
file.txt
Output
ONE:Blablablablabla
blabablabkjhjk
kjbsqbdqbds
TWO:blablabla
ONE:fddsfsdfsdfdsfs
blnskdbbqbbb
xxxxggggggg
TWO:blablabla

Perl - Unexptected behaviour with Regex in Array

I'm trying to match lines that have
"/foldera/folderb/folderc/folderd/file.ext##/main" + "/" + ANY_NUMBER:
so for example:
(.+)(main)(.\d)
The lines:
/foldera/folderb/folderc/folderd/file.ext##/main
/foldera/folderb/folderc/folderd/file.ext##/main/0
/foldera/folderb/folderc/folderd/file.ext##/main/1
/foldera/folderb/folderc/folderd/file.ext##/main/2
/foldera/folderb/folderc/folderd/file.ext##/main/3
/foldera/folderb/folderc/folderd/file.ext##/main/4
/foldera/folderb/folderc/folderd/file.ext##/main/5 (RLT-abcde, BLD-abcde, DEV-abcde)
/foldera/folderb/folderc/folderx/file12.ext##/main/0
/foldera/folderb/folderc/folderx/file12.ext##/main/1
/foldera/folderb/folderc/folderx/file12.ext##/main/2
/foldera/folderb/folderc/folderx/file12.ext##/main/3
/foldera/folderb/folderc/folderx/file12.ext##/main/4
/foldera/folderb/folderc/folderx/file12.ext##/main/5
/foldera/folderb/folderc/folderx/file12.ext##/main/6 (RLS-abcde-5.0, RLS-abcde-4.1)
While my regex matches the desired lines (I checked it at http://www.regexe.com/), in my Perl program it does not match
/foldera/folderb/folderc/folderd/file.ext##/main
but it does match:
/foldera/folderb/folderc/folderd/file.ext##/main/5 (RLT-abcde, BLD-abcde, DEV-abcde)
Here is the code:
use warnings;
use strict;
my #file_list = `find /folder -type f -name '*.ext'|xargs cleartool lsvtree -all`;
foreach my $file(#file_list){
if ($file=~m/(.+)(main)(.\d)/g){
print $file;
}
}
I'm pretty sure that I'm making a stupid mistake somewhere, but I just can't see it!
Thank you in advance for your advice.
P.S. I tried it under Perl 5.8 an Perl 5.18 with the same results, OS is Solaris.
Change
print $file;
to:
print "$MATCH\n";
so you only print the part of the line that was matched by the regexp.
You should also change \d to \d+, to allow for numbers with more than one digit.
Just after a quick look
/foldera/folderb/folderc/folderd/file.ext##/main
Has no number at the end. And \d requires the number ;-)
You may also find this site usefull: http://regexpal.com/
I think is not matching your line because your regex is explicitly looking for a digit at the end
Try changing your regex to be: (Note the curley brackets at the end)
(.+)(main)(.\d){0,1}
Or personally I would write it like this:
(.*?)main(\/\d*){0,1}
Hope this helps!

Regex: Line does NOT contain a number

I've been racking my brain for hours on this and I'm at my wit's end. I'm beginning to think that this isn't possible for a regular expression.
The closest thing I've seen is this post: Regular expression to match a line that doesn't contain a word?, but the solution doesn't work when I replace "hede" with the number.
I want to select EACH line that DOES NOT contain: 377681 so that I can delete it.
^((?!377681).)*$
...doesn't work, along with thousands of other examples/tweaks that I've found or done.
Is this possible?
Would grep -v 377681 input_file solve your problem?
Try this one
^(?!.*377681).+$
See it here on Regexr
Important here is to use the m (multiline) modifier, so that ^ match the start of the line and $ the end of the row, other wise it will not work.
(Note: I recognized that my regex has the same meaning than yours.)
There's probably a better way of doing this, like for example iterating each line and asking for a built String method, like indexOf or contains depending on the language you're using.
Could you give us the full example?
<?php
$lines = array(
'434343343776815456565464',
'434343343774815456565464',
'434343343776815456565464'
);
foreach($lines as $key => $value){
if(!preg_match('#(377681)#is', $value)){
unset($lines[$key]);
}
}
print_r($lines);
?>
You'll need to enable the m (multi-line) flag for the ^ and $ to match the start- and end-of-lines respectively. If you don't, ^ will match the start-of-input and $ will only match the end-of-input.
The following demo:
#!/usr/bin/env php
<?php
$text = 'foo 377681 bar
this can be 3768 removed
377681 more text
remove me';
echo preg_replace('/^((?!377681).)*$/m', '---------', $text);
?>
will print:
foo 377681 bar
---------
377681 more text
---------