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


Groups > comp.lang.php > #10628

Re: CTYPE

Message-ID <36252518.rups8K45Uv@PointedEars.de> (permalink)
From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Organization PointedEars Software (PES)
Date 2013-08-26 10:25 +0200
Subject Re: CTYPE
Newsgroups comp.lang.php
References <kvdg6l$cni$1@speranza.aioe.org> <b7v18bFpg13U1@mid.individual.net> <kvdlrv$si2$1@speranza.aioe.org> <kvdq7d$di5$1@dont-email.me>

Show all headers | View raw


Fiver wrote:

> Your original question was answered, but it seems you have a few
> misconceptions about regular expressions. If you into learning how to do
> things properly, you shouldn't dismiss them out of hand.
> 
> ad 1) "they're never clear to me"
> 
> That's a fair point, as regexes can quickly become hard to read. There's
> a way around that, however: the /x modifier. Take for example the regex
> in the post you replied to (just as an example, I'm not judging its
> correctness for now):
> 
>    preg_match("/^[a-z]\d[a-z] \d[a-z]\d$/i", $postcode)
> 
> This can also be written as
> 
>   $regex = '/
>     ^              # anchored at the start of the string
>     [a-z]          # one letter a-z
>     \d             # one digit 0-9
>     [a-z]          # one letter a-z
>     \s             # one character of white space *
>     \d             # one digit 0-9
>     [a-z]          # one letter a-z
>     \d             # one digit 0-9
>     $              # anchored at the end of the string
>   /ix';
> 
>   preg_match($regex, $postcode)

JFTR: This applies to *Perl* and *Perl-compatible* regular expressions 
(PCRE) only.  PHP also supports POSIX Extended REGular expressions (ERE) 
that do not have that feature.  However, the POSIX ERE functions (ereg*()) 
are deprecated since PHP 5.3 in favor of the PCRE functions (preg_*()).

PHP also supports commenting in PCRE like so:

  $regex = '/'
         . '^(?#      anchored at the start of the string)'
         . '[a-z](?#  one letter a-z)'
         . '\\d(?#    one digit 0-9)'
         . '[a-z](?#  one letter a-z)'
         . '\\s(?#    one character of white space)'
         . '\\d(?#    one digit 0-9)'
         . '[a-z](?#  one letter a-z)'
         . '\\d(?#    one digit 0-9)'
         . '$(?#      anchored at the end of the string)
         . '/ix';

<http://php.net/manual/en/regexp.reference.comments.php>

(In this case, I would pick the PCRE_EXTENDED variant, too.  “(?#…)” is 
better suited for short inline comments.)


Another way, which can be combined with either one, is to use another 
delimiter.  For example, attempting to match an “http:” URI with

  '/http:\\/\\/(?:[^\\/\\s]+)\\/?/'

is safe, but rather hard to read.  It can be written better readable as

  '#http://(?:[^/\\s]+)/?#'

or, with PCRE_EXTENDED enabled,

  '! http:// (?:[^/\\s]+) /? !x'

This can be further simplified to

  '! http:// (?: .+?) /? !x'

and even inline-commented as suggested above (“#” changed to “!” because of 
unescaped “#” delimiting single-line inline comments).
 
> […] a more exact way to match "one space character" would be "[ ]").

Or simply " ".  The character class has the slight advantage over the simple 
assertion that it does not matter how many spaces you write between the 
brackets.  However, character class building might prove to be more 
expensive than the simple assertion, and even if it looks as if there are 
only spaces in-between, a tab character or another non-breaking whitespace 
character could have slipped in – a bug waiting to happen that is easily 
spotted with the simple assertion (it just does not match then).
 
> ad 2) "they're too slow"
> 
> That may have been true in other languages and many, many years ago, but
> it's certainly not the case with PHP today. This regex runs over 2
> million times per second on a single core of my middle-aged laptop. It
> should be more than fast enough, considering I could check every
> Canadian's zip code in under 15 seconds with it... I don't know what
> you're building, but I can guarantee that this won't be the reason for
> any noticeable slow-downs.

It is still true that regular expressions are (or can be) comparably 
expensive with regard to runtime and memory usage, which is why some (non-
PHP) runtime environments disable them by default for security reasons.  
However, if you are using regular expressions for *pattern* matching, the 
program will likely run faster than if you had used plain string operations.  
Because the native machine code (of PHP) has been optimized for that 
purpose.

(Rule of thumb: Explicitly prevent regular expressions from becoming too 
greedy even though in the end they would not match more than they should.  
And do not capture what you do not want to process.  It is *unnecessary* 
backtracking and capturing that makes regular expressions more expensive 
than they could be.)

For example,

  preg_match('/foo/', 'foobar') > 0

has no advantage over

  strpos('foobar', 'foo') !== false

But

  preg_match('/\\bfoo/u', 'foobar') > 0

has as it matches “foo” only at the *start* of a *Unicode* word.

It should also be noted that (Perl-compatible) regular expressions are 
included in one of the ten areas you need to be knowledgable in (“Strings & 
Patterns”), in order to pass the Zend Certified Engineer PHP 5.3 test:

<http://www.zend.com/services/certification/php-5-certification/>


PointedEars
-- 
When all you know is jQuery, every problem looks $(olvable).

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


Thread

CTYPE Twayne <nobody@spamcop.net> - 2013-08-25 13:51 -0400
  Re: CTYPE Richard Yates <richard@yatesguitar.com> - 2013-08-25 11:21 -0700
    Re: CTYPE Twayne <nobody@spamcop.net> - 2013-08-25 15:00 -0400
      Re: CTYPE Richard Yates <richard@yatesguitar.com> - 2013-08-25 12:05 -0700
  Re: CTYPE "J.O. Aho" <user@example.net> - 2013-08-25 20:38 +0200
    Re: CTYPE Twayne <nobody@spamcop.net> - 2013-08-25 15:28 -0400
      Re: CTYPE Richard Yates <richard@yatesguitar.com> - 2013-08-25 13:16 -0700
        Re: CTYPE Twayne <nobody@spamcop.net> - 2013-08-26 11:49 -0400
      Re: CTYPE Christoph Michael Becker <cmbecker69@arcor.de> - 2013-08-25 22:19 +0200
        Re: CTYPE Twayne <nobody@spamcop.net> - 2013-08-26 12:15 -0400
      Re: CTYPE Fiver <numeralfive@gmail.com> - 2013-08-25 22:42 +0200
        Re: CTYPE Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-08-26 10:25 +0200
          Re: CTYPE The Natural Philosopher <tnp@invalid.invalid> - 2013-08-26 09:29 +0100
            Re: CTYPE Twayne <nobody@spamcop.net> - 2013-08-26 12:37 -0400
  Re: CTYPE Norman Peelman <npeelman@cfl.rr.com> - 2013-08-25 15:11 -0400
    Re: CTYPE Tim Streater <timstreater@greenbee.net> - 2013-08-25 23:04 +0100
  Re: CTYPE THREAD RESOLVED Twayne <nobody@spamcop.net> - 2013-08-25 15:35 -0400
    Re: CTYPE THREAD RESOLVED Fiver <numeralfive@gmail.com> - 2013-08-26 20:07 +0200
      Re: CTYPE THREAD RESOLVED The Natural Philosopher <tnp@invalid.invalid> - 2013-08-26 20:19 +0100
        Re: CTYPE THREAD RESOLVED Fiver <numeralfive@gmail.com> - 2013-08-26 22:51 +0200
          Re: CTYPE THREAD RESOLVED Jerry Stuckle <jstucklex@attglobal.net> - 2013-08-26 16:57 -0400
            Re: CTYPE THREAD RESOLVED Twayne <nobody@spamcop.net> - 2013-08-27 17:20 -0400
              Re: CTYPE THREAD RESOLVED Jerry Stuckle <jstucklex@attglobal.net> - 2013-08-27 19:47 -0400
          Re: CTYPE THREAD RESOLVED Tim Streater <timstreater@greenbee.net> - 2013-08-26 22:07 +0100
        Re: CTYPE THREAD RESOLVED Twayne <nobody@spamcop.net> - 2013-08-28 08:49 -0400
      Re: CTYPE THREAD RESOLVED Twayne <nobody@spamcop.net> - 2013-08-27 17:18 -0400

csiph-web