简体   繁体   中英

match regexp against variable string in perl/sed/awk

I have this expression:

XX h, YY min, ZZ s,

XX, YY or ZZ can be 1 or 2 digits. Also "XX h," or "XX h, YY min," maybe not present. Can anyone recommend any perl or sed expression to extract XX YY and ZZ??

I've tried some matching group regexp with no luck.

thanks

EDIT:

example1: 12 h, 23 min, 2 s,

output1: 12 23 2

example2: 3 min, 59 s,

output2: 3 59

Try this (Perl):

my @matches = "1 h, 30 min, 15 s" =~ /(\d{1,2}) [hms]/g;

Or a bit stricter

my @matches = "1 h, 30 min, 15 s" =~ /(\d{1,2}) (?:h|min|s)/g;

if(scalar @matches == 3) {
    my ($h, $mi, $s) = @matches;
    print "$h : $mi : $s\n";
}
echo "12 h, 3 min, 56 s," | tr -cd "0-9 "

Output:

12  3  56

echo "12 h, 3 min, 56 s," | tr "," "\n" | awk '/h/ {print $1}'

12

echo "12 h, 3 min, 56 s," | tr "," "\n" | awk '/min/ {print $1}'

3

echo "12 h, 3 min, 56 s," | tr "," "\n" | awk '/s/ {print $1}'

56

Let's talk about Perl regex. Let's assume you need to be able to extract the following substrings:

12 h, 54 min, 11 s,   # you have a trailing comma in your example
1 h, 54 min, 11 s,
54 min, 11 s,
4 min, 11 s,
55 s,

and so on. We will need some building blocks:

\\d : any digit
? : when appended to something (a character, a meta-character like \\d or a group in brackets), make it optional
( ) : brackets for grouping and extracting values into $1 , $2 , etc.
(?: ) : brackets for grouping without extracting

The seconds part will be \\d\\d? s, \\d\\d? s, .
After adding minutes that can be optional, we'll get (?:\\d\\d? min, )?\\d\\d? s, (?:\\d\\d? min, )?\\d\\d? s, .
After adding hours (also optional), we'll get (?:(?:\\d\\d? h,)? \\d\\d? min, )?\\d\\d? s, (?:(?:\\d\\d? h,)? \\d\\d? min, )?\\d\\d? s, .
Now we'll use brackets around all this staff for capturing the match into $1 and we'll finally get a regex:

/((?:(?:\d\d? h,)? \d\d? min, )?\d\d? s,)/

Or, and is the trailing comma also optional? Just add ? after it.

If you need the values for h , min , and s , put each \\d\\d? into a pair of brackets and check $2 , $3 and $4 :

/((?:(?:(\d\d?) h,)? (\d\d?) min, )?(\d\d?) s,)/

This is not the easiest possible regex for this task but I just wanted to show how you can build them starting from something very simple and then adding more complex things to it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM