in reply to Simple pattern match failing - Possibly unicode issue

Are you sure? I mean, regardles of which characters it's going to match, /\d{2}/ will match two characters exactly. It's never going to match 0748. Regardless of Unicode issues.

Could you provide use with a short snippet of code (including relevant data) that shows this bizarre behaviour? Obviously, the code having the problem isn't the code you are showing; it's hard, if not impossible, to debug code when showing different, working, code.

Replies are listed 'Best First'.
Re^2: Simple pattern match failing - Possibly unicode issue
by cdarke (Prior) on Jun 04, 2010 at 12:01 UTC
    Following up on JavaFan's suggestion, I can reproduce your problem by adding a set of parentheses:
    my $regexp = '(\d{4})(\d{2})(\d{2})\s*((\d{2})(\d{2}))';
    Are you sure your production code does not have them?
Re^2: Simple pattern match failing - Possibly unicode issue
by irahul (Initiate) on Jun 04, 2010 at 14:12 UTC

    /\d{2}/ will always match two characters exactly. But doesn't perl produce polymorphic opcodes for pattern matching which does different things based on the input string encoding? In case of multi-byte encoding, what is /.{2}/ supposed to match? 2 bytes or 2 characters in the given encoding?

    And yes, the code having the problem isn't the code I posted. But I can assure you the code having the problem is doing the same thing. The actual code reads the value of $datetime from a unicode encoded XML file, reads the pattern to match from a config file and populates the fields accordingly. I am dumping both $datetime and $regex before doing a pattern match and they are exactly what I have shown here.

    I have anecdotal evidence that perl's unicode implementation have a role to play in this. I removed:

    use utf8;
    directive and now it works as it's supposed to be.

      /.{2}/ will match two characters. Which may be 4 bytes, or even more. But there's no 2 character UTF-8 byte sequence which, when interpreted as non-UTF-8, will result in a string of 4 ASCII digits.

      And yes, the code having the problem isn't the code I posted. But I can assure you the code having the problem is doing the same thing.
      Ehm, if it's doing the same thing, you wouldn't be having the problem you're encountering. You cannot have two pieces of code "doing the same thing" when one has a problem, and the other doesn't. If they do the same thing, they output the same thing.
      I have anecdotal evidence that perl's unicode implementation have a role to play in this. I removed:
      use utf8;
      That "directive" tells perl your source code is encoded in UTF-8. Since the code fragment you showed contains ASCII only, the use of this pragma is neither wrong, nor necessary.

      I'd really like to see the code that you claim to exhibit the behaviour you describe. You have stumbled upon an (unknown) bug.

      In case of multi-byte encoding, what is /.{2}/ supposed to match? 2 bytes or 2 characters in the given encoding?

      It's quite simple.

      If you match against bytes (e.g. encoded text), it'll match two bytes.
      If you match against chars (e.g. decoded text), it'll match two chars.

      For example, if you match against the four bytes of the UCS-2be encoding of 'AB', you'll get the two bytes 00 and 41.

      '\x{00}\x{41}\x{00}\x{42}' =~ /(.{2})/s; # Two bytes 00 and 41.

      For example, if you match against the four chars NUL, A, NUL, B, you'll get the two chars NUL and A.

      '\x{00}\x{41}\x{00}\x{42}' =~ /(.{2})/s; # Two chars NUL and A
      And yes, the code having the problem isn't the code I posted. But I can assure you the code having the problem is doing the same thing.

      Except that it isn't :) The code you posted will never demonstrate your problem. You should post code that does demonstrate your problem.