Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.php > #9896

Re: PREG \d vs. [0-9]

Message-ID <2167685.t7D80Y4Wy7@PointedEars.de> (permalink)
From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Organization PointedEars Software (PES)
Date 2013-06-26 18:02 +0200
Subject Re: PREG \d vs. [0-9]
Newsgroups comp.lang.php
References <f60593e2-b741-40ba-9355-dcbfd41ac386@googlegroups.com> <8e2894b4-16cf-4599-af33-391fc6570124@googlegroups.com> <kqekud$ap3$1@softins.clara.co.uk> <3829059.0O4M6Kg4EO@PointedEars.de> <51cafdd0$0$6567$9b4e6d93@newsspool3.arcor-online.net>

Show all headers | View raw


Christoph Michael Becker wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Tony Mountifield wrote:
>>> That's because you have an unescaped / within your regex, so it sees
>>> /^M?(([0-9]?)[ ]?([0-9])(/ followed by a ? as a regex modifier.
>> 
>> Good catch.  Also, in POSIX Extended Regular Expressions (ERE) this is
>> written simpler
>> 
>>   ^M?(([0-9]?) ?([0-9])(…
>> 
>> and in Perl-Compatible Regular Expressions (PCRE) it is written simpler
>> 
>>   ^M?((\d?) ?(\d)(…
> 
> Isn't the exact interpretation of \d locale dependent?  I was not able
> to find this information on php.net and I am not able to verify this, as
> I do not have locales available, which have decimal digits other than
> 0-9.  However, at least when one works with UTF-8 encoded strings and
> uses the u modifier for the regular expression, \d is not the same as
> [0-9]:
> 
>   >>> $zero = "\xe0\xa5\xa6" // DEVANAGARI DIGIT ZERO
>   >>> preg_match('/[0-9]/u', $zero)
>   0
>   >>> preg_match('/\d/u', $zero)
>   1

PHP uses Perl-Compatible Regular Expressions (PCRE) here:

<http://php.net/preg_match>
<http://php.net/pcre>

So this can be found in greater detail in the PCRE documentation:

<http://pcre.org/pcre.txt>

“\d” can match more than just “0” to “9” in PCRE, but (unlike in Perl [1]) 
the behavior is _not_ locale-dependent by default.  There is a flag, 
PCRE_UCP, to let \d be equivalent to \p{Digit} etc. (UCP stands for “Unicode 
Character Properties”), but apparently it is not set at compile-time for the 
default PHP distribution:

$ locale
LANG=de_CH.UTF-8
LANGUAGE=
LC_CTYPE="de_CH.UTF-8"
LC_NUMERIC="de_CH.UTF-8"
LC_TIME="de_CH.UTF-8"
LC_COLLATE="de_CH.UTF-8"
LC_MONETARY="de_CH.UTF-8"
LC_MESSAGES=en_US.UTF-8
LC_PAPER="de_CH.UTF-8"
LC_NAME="de_CH.UTF-8"
LC_ADDRESS="de_CH.UTF-8"
LC_TELEPHONE="de_CH.UTF-8"
LC_MEASUREMENT="de_CH.UTF-8"
LC_IDENTIFICATION="de_CH.UTF-8"
LC_ALL=

$ php -r 'echo setlocale(LC_ALL, "de_CH.UTF-8") . "\n";
echo preg_match("/\d/", "१");'
de_CH.UTF-8
0

The “u” expression flag in PHP sets the PCRE_UTF8 run-time flag (as 
documented), but apparently the PCRE_UCP run-time flag as well.  Hence your 
observation:

$ php -r 'echo preg_match("/\d/u", "१");'
1

$ php -v
PHP 5.4.15-1 (cli) (built: May 12 2013 12:17:45) 
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
    with XCache v3.0.1, Copyright (c) 2005-2013, by mOo
    with Xdebug v2.2.1, Copyright (c) 2002-2012, by Derick Rethans
    with XCache Optimizer v3.0.1, Copyright (c) 2005-2013, by mOo
    with XCache Cacher v3.0.1, Copyright (c) 2005-2013, by mOo
    with XCache Coverager v3.0.1, Copyright (c) 2005-2013, by mOo

In Perl there is the “a” flag to let Perl regular expressions match in ASCII 
mode regardless of the locale, but it is not needed with PCRE (when PCRE_UCP 
is not set at compile-time).

[1] <http://perldoc.perl.org/perlre.html>


PointedEars
-- 
Sometimes, what you learn is wrong. If those wrong ideas are close to the 
root of the knowledge tree you build on a particular subject, pruning the 
bad branches can sometimes cause the whole tree to collapse.
  -- Mike Duffy in cljs, <news:Xns9FB6521286DB8invalidcom@94.75.214.39>

Back to comp.lang.php | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

how to change old ereg? astrid.kuhr@gmail.com - 2013-06-25 21:41 -0700
  Re: how to change old ereg? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-06-26 11:47 +0200
  Re: how to change old ereg? Astrid <astrid.kuhr@gmail.com> - 2013-06-26 04:29 -0700
    Re: how to change old ereg? tony@mountifield.org (Tony Mountifield) - 2013-06-26 11:57 +0000
      Re: how to change old ereg? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-06-26 14:13 +0200
        PREG \d vs. [0-9] (was: how to change old ereg?) Christoph Michael Becker <cmbecker69@arcor.de> - 2013-06-26 16:42 +0200
          Re: PREG \d vs. [0-9] Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-06-26 18:02 +0200
      Re: how to change old ereg? Gregor Kofler <usenet@gregorkofler.com> - 2013-06-26 21:34 +0200
        Re: how to change old ereg? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-06-27 01:18 +0200
          Re: how to change old ereg? The Natural Philosopher <tnp@invalid.invalid> - 2013-06-27 12:55 +0100
  Re: how to change old ereg? Astrid <astrid.kuhr@gmail.com> - 2013-06-26 05:24 -0700
  Re: how to change old ereg? Astrid <astrid.kuhr@gmail.com> - 2013-06-28 01:38 -0700
    Re: how to change old ereg? tony@mountifield.org (Tony Mountifield) - 2013-06-28 09:02 +0000
      Re: how to change old ereg? Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-06-28 12:39 +0200
      Re: how to change old ereg? Denis McMahon <denismfmcmahon@gmail.com> - 2013-06-28 11:08 +0000
  Re: how to change old ereg? Astrid <astrid.kuhr@gmail.com> - 2013-06-28 02:46 -0700
    Re: how to change old ereg? Jerry Stuckle <jstucklex@attglobal.net> - 2013-06-28 08:48 -0400

csiph-web