in reply to Re: Combining regexes
in thread Combining regexes

Much reading later - and thank you for all the references in your other post, only some of which I had read previously - I think I understand what you are doing. I do have some questions, though. Am I right in thinking that the (?i) has the same effect as an i qualifier with xmsr? If not, what is the difference (and where is it documented, please)? If so, and I appreciate that you have stated "my own preferred practices" which exempts you from needing a reason, is there a reason why you prefer to have the qualifiers separately?

How come none of the spaces in { \A (?i) \Q$startdir\E \\? } are treated as matchable characters? I suspect it's one of your qualifiers, but I couldn't find it explained in any of the docs I read, unless it's part of x, and I haven't looked for the documentation for that beyond reading that it means "extended regexes".

I find your final assignment ($var = $var =~ regex =~ regex) rather confusing, as it seems to need to work from left to right at some times and from right to left at others. I know things joining things like map, grep & sort result in the expression working right to left. I don't remember seeing three assignment-like = signs in a Perl statement before, which may be part of my confusion. Is the order irrelevant, and if not, what are the rules for the direction of evaluation?

Thanks and regards,

John Davies

Replies are listed 'Best First'.
Re^3: Combining regexes
by AnomalousMonk (Archbishop) on May 21, 2016 at 22:22 UTC
    Am I right in thinking that the (?i) has the same effect as an i qualifier with xmsr?

    Yes — almost. In, e.g.,  s{ ... }{...}xmsi the  /i modifier affects the regex match globally. A  (?i) extended pattern only has effect from the point of its appearance in the regex to the end of the regex pattern scope — which may or may not be the end of the regex! (See Extended Patterns. I must apologize: I did not mention that extended patterns are only available from Perl version 5.10 onward; I assume you have this.) I prefer the embedded  (?i) form because it is more visible and because it gives more control: case sensitivity can be turned on and off at will in a regex, and its scope closely controlled. In general, "my own preferred practices" are that the  qr// operator has only the  /xms modifiers applied to the operator, and all other modifiers , e.g., (?i), scoped within the operator. This practice just generalizes to the  m//xms and  s///xms operators. The latter two operators can also take  /g /e /r modifiers which can only be applied to the operator as a whole.

    ... none of the spaces in { ... } are treated as matchable characters? I suspect it's ... x ...

    Yes, exactly. Allowing whitespace not to be part of the pattern eases the strain on these old eyes, a great blessing after so many years toiling in the scriptorium. See  /x in Modifiers.

    I find your final assignment ($var = $var =~ regex =~ regex) rather confusing, as it seems to need to work from left to right at some times and from right to left at others.

    It might have been helpful if I had thrown in a few disambiguating parentheses. But you can always add your own with O and B::Deparse:
    (Here I wanted to give an example of the deparsed code, but for some reason I don't understand, it didn't work out! Quickly moving on...)
    Anyway, by hand:

    c:\@Work\Perl\monks>perl -wMstrict -le "my $curdir = 'Y:\Music\Schubert\Lieder\Terfel'; my $startdir = 'Y:\mUsIc'; ;; my $plsname = ((($curdir =~ s{ \A (?i) \Q$startdir\E \\? }{}xmsr) =~ tr{\\}{_}r) +. '.pls'); print qq{'$plsname'}; " 'Schubert_Lieder_Terfel.pls'
    Working in order of precedence (more or less inside-out in this case):
    1. ($curdir =~ s{ \A (?i) \Q$startdir\E \\? }{}xmsr)
      A substitution is done on  $curdir and the substituted string returned courtesy of the  /r modifier of 5.14+;
    2. (($curdir =~ s{ ... }{}xmsr) =~ tr{\\}{_}r)
      The string returned by the  s///r substitution is operated upon by  tr///r and the translated string is returned;
    3. ((($curdir =~ s{ ... }{}xmsr) =~ tr{\\}{_}r) . '.pls')
      The string  '.pls' is appended to the string returned by  tr///r and;
    4. The whole thing is finally assigned to $plsname. Whew!

    Is the order irrelevant, and if not, what are the rules for the direction of evaluation?

    The order is very relevant, and is discussed in Operator Precedence and Associativity in perlop: see the  =~ (binding) and  . (concatenation) and  = (assignment) operators.

    Update: Layout of  <ol> above changed – improved?


    Give a man a fish:  <%-{-{-{-<