$ perl -E '
> $data = q{10 1/0/6/0/0.1.20.0.0.2.1 c10t2d1 FA};
> $dev = ( split m{\s+}, $data )[ 2 ];
> say $dev;'
c10t2d1
$
I hope this is helpful.
| [reply] [d/l] |
I liked JohnGG's split idea. This is a fine way to go when the data is white-space separated.
I would just point out that it is also possible to specify an index from the end of the array for the list slice. Instead of saying "2" which means skip 0 and 1, you can say -2 which means next to last in the array, [-1] is the last thing in the array (FA). Sometimes this helps if there is a lot of things on the line or if number of things varies. Here 2 and -2 mean the same thing and is just a coincidence.
If this c,t,d fields are always there, then extracting the digits is easy with match global:
my $dev = "c10t2d1";
my($c,$t,$d) = $dev =~ m/\d+/g;
print "$c $t $d";
#prints: 10 2 1
If you need a regex, say line can end in other things than FA, then one way is anchor the regex to the end of the line and "work backwards", one way:
my $test = "10 1/0/6/0/0.1.20.0.0.2.1 c10t2d1 FA ";
my ($ctd) = $test =~ m/(\w+)\s+FA\s*$/;
print $ctd;
#prints: c10t2d1
| [reply] [d/l] [select] |
\b will match between a \w character and a \W character and \B will match between two \w characters or between two \W characters.
I have tried
print if /\B.\d+.\d+\s+.?\s+\B/;
print if /\B.\d+.\d+\s+.?\s+\B/FA;
print if /\B.\d+\s+\w+\B/FA;
Your examples start off with \B.\d+ which says match at a \B boundary then match any character (except newline) then match one or more digits. So if the any character before the digits is a \w character then there must be at least two \w characters before the digits or if the any character before the digits is a \W character then there must be at least two \W characters before the digits.
The only strings in your example that will match that pattern are "c10" or "0t2" or "2d1".
| [reply] [d/l] [select] |
In your question, are you using '#' as wildcards? Does that mean that c, t, and d will always be present in a suitable match? Will there always be whitespace on either side of a suitable capture? If so:
if( $_ =~ m/\s(c\d+t\d+d\d+)\s/ ) {
print $1;
}
| [reply] [d/l] |
If you really want to print what is between .1 and FA, you can try something like the following:
print $1 if /\.1\s+(.*?)\s+FA/;
| [reply] [d/l] |