Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I parse from last \ to end of line ? 1

Status
Not open for further replies.

goliath

MIS
Aug 18, 1999
62
0
0
US
Try as I might,

I need to parse the information from a line read in and get everything from the last backslash (\) to the end of the line (\n).

I've tried a few things but have a feeling I'm way off base. Will I need to do a split function? I'm still learning, so be gentle.

My best guess was this below, but I know thats not right...

$line =~ /\\$(.*?)\n/;

Thanks!
 
#!perl -W
# was this what u want ?
use strict;
my $brut = "1111\\222222\\3333333\\hello\n44444";
my @clean = split(/\\/, $brut);
my $lenght = @clean;
my $almost = $clean[$lenght - 1];
my @finals = split(/\n/, $almost);
my $wanted = $finals[0];
print $wanted; ---------------------------------------
wmail.jpg


someone knowledge ends where
someone else knowledge starts
 
Here are two ways using a modification of your attempted regex. The first is non-destructive and the second is destructive (i.e. it modifies the original variable)

my $line = "first\\second\\third\\last\n";
my ($base) = $line =~ /\\([^\\]+)\n/;
$line =~ s/.*\\([^\\]+)\n/$1/;

jaa
 
hi justice ! im not to used to regex ..could u show me ?
could u make the regex :
retrieve 'hello' in $line
retrive '1111\\222222\\3333333\\' in $line

my $line = "1111\\222222\\3333333\\hello\n44444";
thanks ---------------------------------------
wmail.jpg


someone knowledge ends where
someone else knowledge starts
 
Here's a breakdown of matching from the following string what you asked for:

my $line = "1111\\222222\\3333333\\hello\n44444\\last\n";

I made it slightly more challenging by adding a second possible match at the end. Now there are two words that are preceeded by a '\' and followed by a '\n', 'hello' and 'last'.

A first attempt might be:

my ($prepath1, $base1) = $line =~ /(.*\\)(.*)\n/;
# $prepath1 == '1111\222222\3333333\'
# $base1 == 'hello'

Which actually works. The '(.*\\)' greedily matches everything up to the last '\' that it finds and captures it all, along with the '\' into $1. The '(.*)' captures everything after the '\' up to a '\n' into $2. The reason that this matched the 'hello' and not the 'last' is because the wildcard '.' does not match '\n' by default. You have to use the /s modifier to get this behavior.

my ($prepath2, $base2) = $line =~ /(.*\\)(.*)\n/s;
# $prepath2 == '1111\222222\333333\hello\n44444\'
# $base == 'last'


All of the following give the same result as the first example:
my ($prepath3, $base3) = $line =~ /(.*\\)([^\\]+)\n/;
my ($prepath4, $base4) = $line =~ /(.*?\\)([^\\]+)\n/;
my ($prepath5, $base5) = $line =~ /(.*?\\)([^\\]+)\n/s;
# $prepath1 == '1111\222222\3333333\'
# $base1 == 'hello'

But now the match for 'hello' is more rigid (it must be a non-'\' character, which is what the '[^\\]+' does: one or more non-'\' chars). So even making the prepath match non-greedy (by adding a '?' after the '.*') doesn't make a difference. Compare this to making the first example non-greedy:

my ($prepath6, $base6) = $line =~ /(.*?\\)(.*)\n/;
# $prepath6 == '1111\'
# $base6 == '222222\3333333\hello'

Now the '(.*?\\)' only matches up to the FIRST '\' that it finds and the '(.*)' captures the rest up to the newline.

That's probably more than you really wanted.

jaa
 
yes but thanks ! ---------------------------------------
wmail.jpg


someone knowledge ends where
someone else knowledge starts
 
I've read and re-read that post by justice41 but am not fully following it...

Anywhoo - my challenge has changed just a little.

I need to obtain the last lenght of data following whichever comes last, a colon or a backslash...

For example, data could be:
myname:\pookie
myname\pookie
myname:\pook\pookiepoo\pookie
myname:myname2:pookie

it will always be the data after the last colon or backslash. I thought I had it but it turns out my code doesnt work right... Is there some way to parse from right to left then stop at the first colon or backslash? Thats what I'm investigating now...

Thanks in advance!
 
This is similar to the previous one. You want everything that is not a '\' or ':', which is the character class [^\\:] (the ^ inside a character class negates everything in it). Since you want the data after the last '\' or ':', you want everything that matches up to the end of the string. So

if ( $line =~ /([^\\:]+)$/ ) {
$base = $1;
}

jaa
 
Could also try this one.

$base = (split /[\\:\n]/,$line)[-1];

This splits $line on \, :, or newline (so you don't have to chop it off, if you're reading this list from a file), then returns the last element of the list.

Richard
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top