0

Below is the script i used to capture the secs

use strict;
use warnings;

my $n='Created posting 187294181 (sny/sny_AF8F46748A50416A9F1FF2BD7) in 0.261 secs';
my $m='Created posting 187294183';


if($n=~/Created\s+(resume|posting)\s+(\d+).*?([\d\.]*)/i)
{
   print "$1 $2 $3\n";
}

Iam getting $3 as blank.Can anyone help me what mistake i have done in the regex to capture secs.Both the $m and $n should match the regex.

Output:

posting 187294181 
Venkatesan
  • 342
  • 3
  • 5
  • 16

1 Answers1

1

Use this regex:

(resume|posting) (\d+)(?:.*?in ([\d.]+) secs)?

In the demo, inspect the capture Groups in the right pane.

In your Perl code:

if ($subject =~ m/(resume|posting) (\d+)(?:.*?in ([\d.]+) secs)?/i) {
   # We matched!
   print "$1 $2";
   # Is Group 3 set? 
   if (defined $3) { print "$3"; }
   print "\n";
}

Explanation

  • (resume|posting) captures resume or posting to Group 1.
  • (\d+) captures the digits to Group 2.
  • (?: opens our optional non-capture group
  • .*? lazily matches chars up to ....
  • the literal in, then
  • ([\d.]+)we capture the time to Group 3
  • match literal chars secs
  • )? closes the non-capture group and makes it optional
zx81
  • 38,175
  • 8
  • 76
  • 97
  • FYI added [demo](http://regex101.com/r/fQ1iD5/4), please have a look at the capture groups in the right pane. :) Will add explanation. – zx81 Jun 30 '14 at 06:44
  • He might have an issue with $3 sometimes being undefined. `for ($n, $m) { if (/Created \s+ (resume|posting) \s+ (\d+) \b (?: .*? \b in \s+ \b ([\d.]+) \b \s+ secs) ? /x) { printf "1=%s 2=%s 3=%s\n", $1, $2, defined($3) ? $3 : "" } `. There are better ways of matching floats, and as written there may be false positives on nefarious naughty data. But if all data are “guaranteed” good, well, then ok. – tchrist Jun 30 '14 at 06:46
  • 1
    If only people just write in `/x` mode all the time, they would never have to have these extra explanations; that would be in the comments. – tchrist Jun 30 '14 at 06:50
  • @tchrist Yes I'm aware that the float-matching is quick-and-dirty, that seemed alright with his input. Group 3 is inside an optional non-cap group so he needs to test it in the `if`. But I'm sure you know all that. – zx81 Jun 30 '14 at 06:50
  • If using v5.10 or higher, of course `$3 // ""` is also possible, and only evaluates `$3` once. Which isn’t a big deal, but still. – tchrist Jun 30 '14 at 06:51
  • @tchrist I'm a big fan of `/x` / `(?x)` / `VERBOSE`, but for some reason on short SO answers they often scare people away. :) I end up creating these explanations by hand as I wasn't happy with automated tools (they divide into tokens, whereas to explain to a human, you need to find the right unit) – zx81 Jun 30 '14 at 06:52
  • @tchrist Okay, added the whole test so that he prints $1, $2 and optionally $3. :) – zx81 Jun 30 '14 at 06:57
  • Compiling with `VERBOSE` works in Python, yes. But Java’s implementation is rather nasty: you end up having to put `\n` as a two-character escape in the pattern to stop the `# comment \n`, which rather sucks. – tchrist Jun 30 '14 at 06:57
  • Sigh. What is this non-inlined "demo" habit that people seem to think is some sort of good idea? Unless you run it through Perl, you will never be sure it works that way, and PCRE != Perl. However, a link to a video running it under Damian’s `Regex::Debugger` module: that would be really cool. – tchrist Jun 30 '14 at 07:00
  • @tchrist Here's [a monster](http://stackoverflow.com/a/24463086/1078583) I'm working on, wouldn't dream of it without `(?x)`... Completed part B, working on part C. Btw also love `DEFINE` for refactoring, do you use that? @HamZa uses it very efficiently and I've been starting to make manageable monsters with it. – zx81 Jun 30 '14 at 07:01
  • Yes, I do use `DEFINE`. [Look at some of my gnarlier regex answers.](http://stackoverflow.com/search?q=user%3A471272+%5Bregex%5D) It allows you to do top-down programming again, with regex subroutines. It’s a bit slow though in that the optimizer can’t get all clever with it. – tchrist Jun 30 '14 at 07:02
  • Yes, looking at your answers is on my list!!! I'm retiring from a few weeks of intense answering as of July 1st so will have more time. :) Regarding `DEFINE`, don't think it exists in Barnett Python, I scribbled an idea to replace it the other day but haven't fully tested it: `(?:(Tigers)$^)?match whatever(?1)` So here Group 1 is a definition for `Tigers` – zx81 Jun 30 '14 at 07:05
  • Right, `DEFINE` is only in Perl and PCRE last I checked, and not yet in Barnett’s great Python `regex` module. The last few regexes [in the number-matching answer](http://stackoverflow.com/a/4247184) use `(?&GROUPNAME)` stuff for easier writing and reading. – tchrist Jun 30 '14 at 07:08
  • Aha. I'll double check. Here's a demo of my [DIY DEFINE for Python](http://regex101.com/r/rK1rY7/1) (engine is PCRE but would work in `regex` module) – zx81 Jun 30 '14 at 07:13