Results 1 to 5 of 5

Thread: Perl regex - How to make my greedy quantifier greedier?

  1. #1
    Join Date
    Sep 2010
    Beans
    Hidden!
    Distro
    Ubuntu 12.04 Precise Pangolin

    Perl regex - How to make my greedy quantifier greedier?

    Hello schragge and trent.josephsen,

    Thank you very much for your valuable reply.

    Both of your suggestions worked for me.

    Now, I have the following outputs.
    Code:
    $ find testing -type f -name "[a-z]*\.txt"
    testing/dir.a/dir_b/dir-c/this-is-testing4_org.txt
    testing/dir.a/dir_b/dir-c/this_is_testing3_org.txt
    $ ls testing/dir.a/dir_b/dir-c/* | perl -ne 'm{^(.*/)([a-z][^/]*)$} && print'
    testing/dir.a/dir_b/dir-c/this_is_testing3_org.txt
    testing/dir.a/dir_b/dir-c/this-is-testing4_org.txt
    $ ls testing/dir.a/dir_b/dir-c/* | perl -MFile::Basename -ne 'print if basename($_) =~ /^[a-z]/'
    testing/dir.a/dir_b/dir-c/this_is_testing3_org.txt
    testing/dir.a/dir_b/dir-c/this-is-testing4_org.txt
    Best Regards,
    cibalo
    Last edited by cibalo; May 18th, 2013 at 01:51 AM.

  2. #2
    Join Date
    Feb 2009
    Beans
    1,469

    Re: Perl regex - How to make my greedy quantifier greedier?

    Can you be a little more clear? What's wrong with what the find command outputs?

    Changing the greediness of quantifiers only changes what certain subpatterns will match, and can make a pattern match more or less efficient, but can't change whether the pattern as a whole will match.

    Or do you want non-backtracking? I think that's possible by some switch or other. Not the best way to do what looks to be a simple match, though.

  3. #3
    Join Date
    Sep 2010
    Beans
    Hidden!
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: Perl regex - How to make my greedy quantifier greedier?

    I just want to know if perl regex can get the same result as my find command outputs.
    Maybe my regex is wrong.
    However, if you have any idea that make the perl regex works.

  4. #4
    Join Date
    Feb 2013
    Beans
    Hidden!

    Re: Perl regex - How to make my greedy quantifier greedier?

    As trent.josephsen said, preventing backtracking should help here
    Code:
    perl -ne 'print $1, " - ", $2, "\n" if /^((?>.*\/))([a-z].*)$/'
    But then, why not just
    Code:
    perl -ne 'print $1, " - ", $2 if m{^(.*/)([a-z][^/]*)$}'
    Last edited by schragge; May 17th, 2013 at 09:34 AM.

  5. #5
    Join Date
    Feb 2009
    Beans
    1,469

    Re: Perl regex - How to make my greedy quantifier greedier?

    Right, that was exactly what I was going to suggest. Non-backtracking subpatterns are an advanced technique I wouldn't really use for something this simple.

    Then again, I'd probably use File::Basename, which makes the intent a bit more explicit:

    Code:
    $ ls testing/dir.a/dir_b/dir-c/* | perl -MFile::Basename -ne 'print if basename($_) =~ /^[a-z]/'
    testing/dir.a/dir_b/dir-c/This-is-testing2_org.txt
    testing/dir.a/dir_b/dir-c/This_is_testing1_org.txt
    Even better, use /^[[:lower:]]/ for extra portability.

    The reason your second pattern behaves the way it does is because you've provided no way to avoid the print statement. If the match fails, $1 and $2 don't get changed, and print displays the same things that matched last time through the loop. That's why both schragge's and my solutions use an if modifier.

    TMTOWTDI as usual.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •