Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Capturing regex from map

by trippledubs (Deacon)
on Sep 13, 2013 at 14:41 UTC ( [id://1053954]=perlquestion: print w/replies, xml ) Need Help??

trippledubs has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

Is it Monk-like to capture regex from map like the following:

my @online_services = map { /^online.*svc:(.*?):/ } `svcs`;

I started using this pattern quite a bit, but I am wondering if this is not desirable for some reason.

Replies are listed 'Best First'.
Re: Capturing regex from map
by Athanasius (Archbishop) on Sep 14, 2013 at 04:34 UTC

    I agree with the other monks, there’s nothing wrong with using map. However, it is possible to get an equivalent result without map by rearranging and adding the /g and /m modifiers to the regex:

    my @online_services = `svcs` =~ /^online.*svc:(.*?):/gm;

    Note that this works because the binding operator puts its left-hand operand into scalar context; and backticks (or qx//) in scalar context return “a single (potentially multi-line) string” (Quote Like Operators).

    My benckmark tests suggest that this approach may also be more efficient:

    But by all means stick with map if you’re more comfortable with it.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Capturing regex from map
by NetWallah (Canon) on Sep 13, 2013 at 17:43 UTC
    The code is Efficient, concise, clear, and correct.

    I see no reason to change it.

    Wondering + Action on discovery => progress.

    (I ++'d 2 of your nodes in this thread - enjoy your XP!.)

                 My goal ... to kill off the slow brain cells that are holding me back from synergizing my knowledge of vertically integrated mobile platforms in local cloud-based content management system datafication.

Re: Capturing regex from map
by BrowserUk (Patriarch) on Sep 13, 2013 at 16:38 UTC
    but I am wondering if this is not desirable for some reason.

    Why are you wondering that? If it is working for you; what makes you think it might be "not desirable"?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Well possibly I was thinking that it has only worked "so far" and that some landmine is potentially waiting, since I haven't seen that construct elsewhere. I'm not exposed to a lot of code though so I usually suspect any original thought is either not original or wrong for some reason I haven't thought of. I usually see something like
      my ($match_1,$match_2) = ($string =~ /(.*):(.*)/) // And in my own scripts I'm using constructs like my ($wanted_service) = (map { /^online.*svc:(.*?):/ } `svcs`)[15];
      Someone asked me, what is the best way to do x, I reach for the handy regex mapper, but I'm not sure it is the best. In sum: lack of confidence and the competitive drive for perfection. AND to a smaller degree, I want more xp. Why did you wonder why I wondered? This might go on all day, maybe I'll level up! :)
        Why did you wonder why I wondered?

        Because most times when this kind of question -- someone second guessing a piece of working code -- comes up, there is usually some clue, either in the post, or in the history of this place, to indicate what the fear that underlies the question is.

        With your question I detect nothing that indicates either a commonly frowned upon, but otherwise workable construct -- as we often see with map in a scalar or void context for example -- nor anything in your post to indicate the basis of your doubts.

        I cannot see any reason not to use the construct for those occasions when it does the required task. It is concise and to my eyes clear. But, there is the possibility that I'm missing something, hence I wanted to know more ...


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Capturing regex from map
by Laurent_R (Canon) on Sep 13, 2013 at 15:04 UTC

    If this works for you, why not, but also take a look at the grep function.

      ...take a look at the grep function...

      Help me understand how grep will pass only the captures from a regex, as map does in this case.

        You are right, grep will not do captures in such a situation. I might not have been clear, but I only mentionned is as an additional useful tool in similar synctactic context, for filtering purpose.

        Having said that you can do something akin to captures in a grep, although it is not very clean. Consider this:

        DB<1> @a = qw (foobar barfoo foobaz, bar, foobor); DB<2> @c = grep {s/fo(ob.).+/$1/} @a; DB<3> x @c 0 'oba' 1 'oba' 2 'obo'

        Not clean, I would not really recommend it, but not impossible.

Re: Capturing regex from map
by thezip (Vicar) on Sep 13, 2013 at 17:02 UTC

    Try:

    my @online_services = map { /^online.*svc:(.*?):/; $1 } `svcs`;

    What can be asserted without proof can be dismissed without proof. - Christopher Hitchens, 1949-2011
      > try my @online_services = map { /^online.*svc:(.*?):/; $1 } `svcs`;

      not equivalent:

      DB<217> map { /(1\d*)/;$1 } 5..15 => (undef, undef, undef, undef, undef, 10, 11, 12, 13, 14, 15) DB<218> map { /(1\d*)/ } 5..15 => (10, 11, 12, 13, 14, 15)

      Cheers Rolf

      ( addicted to the Perl Programming Language)

      update

      I think you meant:

      DB<225> map { @matches=/(1\d*)/;@matches} 5..15 => (10, 11, 12, 13, 14, 15)

        That's what I get for not testing! </sheepish grin>


        What can be asserted without proof can be dismissed without proof. - Christopher Hitchens, 1949-2011
        A reply falls below the community's threshold of quality. You may see it by logging in.
      I'd say map { /^online.*svc:(.*?):/; $1 || () }

      just to be clear on what the expected transformation is. I feel that a regexp-match inside a map is fairly abstruse.

        Some other variants:
        map { /^online.*svc:(.*?):/; $1 // () } map { /^online.*svc:(.*?):/ and $1 or () } map { /^online.*svc:(.*?):/ ? $1 : () }
        The latter two are easy to extend if there are multiple captures. (The middle one is my favourite.)
        This is definitely clearer, I'd recommend it.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1053954]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2024-04-19 12:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found