preg_match too greedy

preg_match too greedy

am 29.07.2009 19:42:23 von B

I'm trying to figure out how to test if a string matches *exactly*
another string, using a regexp pattern. The manual says that ereg() is
deprecated (in favour of what?) and preg_match() is giving me trouble.
The problem is that I'm passing the end-of-line delimiter ($) but it
seems to be ignored. An example:

-- snip --
header('Content-type: text/plain');
$url = '/foo(/)?';
$test = 'foo/bar';
$pattern = '%^'.$url.'$%U';

echo "${url} :: ${test}\n";

echo (preg_match($pattern, $test) != false)
? 'match'
: 'no match';
-- snip --

I expected 'no match' but get 'match'.

The reason for the (/)? is to allow for a trailing slash. I've added a
'$' to specify that I want to test for the exact string. However,
preg_match() tests for the existence of a string and appears to ignore
the '$'.

How do I do this?

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 29.07.2009 20:07:00 von List Manager

b wrote:
> I'm trying to figure out how to test if a string matches *exactly*
> another string, using a regexp pattern. The manual says that ereg() is
> deprecated (in favour of what?) and preg_match() is giving me trouble.
> The problem is that I'm passing the end-of-line delimiter ($) but it
> seems to be ignored. An example:
>
> -- snip --
> header('Content-type: text/plain');
> $url = '/foo(/)?';
> $test = 'foo/bar';
> $pattern = '%^'.$url.'$%U';
>
> echo "${url} :: ${test}\n";
>
> echo (preg_match($pattern, $test) != false)
> ? 'match'
> : 'no match';
> -- snip --
>
> I expected 'no match' but get 'match'.
>
> The reason for the (/)? is to allow for a trailing slash. I've added a
> '$' to specify that I want to test for the exact string. However,
> preg_match() tests for the existence of a string and appears to ignore
> the '$'.
>
> How do I do this?
>

cut/paste your code and it works for me.

Jim Lucas


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 29.07.2009 21:03:10 von Ben Dunlap

Jim Lucas wrote:
>> I expected 'no match' but get 'match'.
[8<]
> cut/paste your code and it works for me.

Works for me as well. I get 'no match' from PHP 5.1.2, 5.2.6, and 5.2.8. What
version do you have?

If I might suggest a couple of simplifications that would make it easier to
follow/troubleshoot:

>> $url = '/foo(/)?';

I don't think you need parentheses around your second forward-slash. If you had
multiple characters that were optional you'd want to group them in parentheses,
but here I think it just makes the regex harder to read.

>> echo (preg_match($pattern, $test) != false)

The " != false " here is redundant. Combined with the ternary operator, the
logical switchbacks make me a little dizzy (especially this close to lunchtime).

Ben

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 29.07.2009 21:18:54 von List Manager

Ben Dunlap wrote:
> Jim Lucas wrote:
>>> I expected 'no match' but get 'match'.
> [8<]
>> cut/paste your code and it works for me.
>
> Works for me as well. I get 'no match' from PHP 5.1.2, 5.2.6, and 5.2.8. What
> version do you have?

PHP 5.2.5 with Suhosin-Patch 0.9.6.2 (cli) (built: Mar 11 2008 13:08:50)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
with Suhosin v0.9.20, Copyright (c) 2002-2006, by Hardened-PHP Project


>
> If I might suggest a couple of simplifications that would make it easier to
> follow/troubleshoot:
>
>>> $url = '/foo(/)?';
>
> I don't think you need parentheses around your second forward-slash. If you had
> multiple characters that were optional you'd want to group them in parentheses,
> but here I think it just makes the regex harder to read.
>
>>> echo (preg_match($pattern, $test) != false)
>
> The " != false " here is redundant. Combined with the ternary operator, the
> logical switchbacks make me a little dizzy (especially this close to lunchtime).
>
> Ben
>



--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 30.07.2009 01:28:49 von Clancy

On Wed, 29 Jul 2009 13:42:23 -0400, php@logi.ca (b) wrote:

>I'm trying to figure out how to test if a string matches *exactly*
>another string, using a regexp pattern.

If this is REALLY what you want to do, what is wrong with strcmp?


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 30.07.2009 01:48:42 von Daniel Kolbo

Jim Lucas wrote:
> Ben Dunlap wrote:
>> Jim Lucas wrote:
>>>> I expected 'no match' but get 'match'.
>> [8<]
>>> cut/paste your code and it works for me.
>> Works for me as well. I get 'no match' from PHP 5.1.2, 5.2.6, and 5.2.8. What
>> version do you have?
>
> PHP 5.2.5 with Suhosin-Patch 0.9.6.2 (cli) (built: Mar 11 2008 13:08:50)
> Copyright (c) 1997-2007 The PHP Group
> Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
> with Suhosin v0.9.20, Copyright (c) 2002-2006, by Hardened-PHP Project
>
>
>> If I might suggest a couple of simplifications that would make it easier to
>> follow/troubleshoot:
>>
>>>> $url = '/foo(/)?';
>> I don't think you need parentheses around your second forward-slash. If you had
>> multiple characters that were optional you'd want to group them in parentheses,
>> but here I think it just makes the regex harder to read.
>>
>>>> echo (preg_match($pattern, $test) != false)
>> The " != false " here is redundant. Combined with the ternary operator, the
>> logical switchbacks make me a little dizzy (especially this close to lunchtime).
>>
>> Ben
>>
>
>
>
code works (no match) for me too on php 5.2.6 build date May 2 2008
18:01:20 with dumbdows NT.

preg_match fails but for a reason other than what I think you may be
expecting. It fails b/c of the first forwards slash in $url. The regex
engine doesn't even get past the second character let alone reaching the
end of line anchor.

Also, your code works (no match) with this first forward slash removed:
$url = 'foo(/)?'
This time preg_match fails due to the end of line anchor.
hth
dK
`

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 30.07.2009 04:06:07 von B

On 07/29/2009 02:07 PM, Jim Lucas wrote:
> b wrote:
>> I'm trying to figure out how to test if a string matches *exactly*
>> another string, using a regexp pattern. The manual says that ereg() is
>> deprecated (in favour of what?) and preg_match() is giving me trouble.
>> The problem is that I'm passing the end-of-line delimiter ($) but it
>> seems to be ignored. An example:
>>
>> -- snip --
>> header('Content-type: text/plain');
>> $url = '/foo(/)?';
>> $test = 'foo/bar';
>> $pattern = '%^'.$url.'$%U';
>>
>> echo "${url} :: ${test}\n";
>>
>> echo (preg_match($pattern, $test) != false)
>> ? 'match'
>> : 'no match';
>> -- snip --
>>
>> I expected 'no match' but get 'match'.
>>
>> The reason for the (/)? is to allow for a trailing slash. I've added a
>> '$' to specify that I want to test for the exact string. However,
>> preg_match() tests for the existence of a string and appears to ignore
>> the '$'.
>>
>> How do I do this?
>>
>
> cut/paste your code and it works for me.
>
> Jim Lucas
>

Works, meaning you get 'match', or 'no match'? It should be the latter,
but I'm seeing the former.

I'm using 5.2.9, btw.

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 30.07.2009 04:16:34 von B

On 07/29/2009 03:03 PM, Ben Dunlap wrote:
> Jim Lucas wrote:
>>> I expected 'no match' but get 'match'.
> [8<]
>> cut/paste your code and it works for me.
>
> Works for me as well. I get 'no match' from PHP 5.1.2, 5.2.6, and 5.2.8. What
> version do you have?

5.2.9

> If I might suggest a couple of simplifications that would make it easier to
> follow/troubleshoot:
>
>>> $url = '/foo(/)?';
>
> I don't think you need parentheses around your second forward-slash. If you had
> multiple characters that were optional you'd want to group them in parentheses,
> but here I think it just makes the regex harder to read.

Really? I think it makes it crystal clear that it's the '/' that is
optional. In any case, it makes no difference.

>
>>> echo (preg_match($pattern, $test) != false)
>
> The " != false " here is redundant.

Understood. But what you think is redundancy is, to me, clarity in
programming. I happen to think that boolean tests shouldn't ride on
whether or not an array returned from a function is empty or not (or a
freaking boolean). If what I'm looking for is a "false" then that's what
I'll test for.

> Combined with the ternary operator, the logical switchbacks make me a
> little dizzy (especially this close to lunchtime).
>

Oh, you're one of those people who can't stand the sight of a ternary
operator. Buck up, son, it's good for ya ;-)

(Seriously: I don't understand why ternaries freak some people out. It's
plain as day!)


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 30.07.2009 04:19:31 von B

On 07/29/2009 07:48 PM, Daniel Kolbo wrote:
>
> code works (no match) for me too on php 5.2.6 build date May 2 2008
> 18:01:20 with dumbdows NT.
>
> preg_match fails but for a reason other than what I think you may be
> expecting. It fails b/c of the first forwards slash in $url. The regex
> engine doesn't even get past the second character let alone reaching the
> end of line anchor.

The forward slash shouldn't be an issue as the delimiter is '%'. The
full pattern is:

%^/foo/?$%U


> Also, your code works (no match) with this first forward slash removed:
> $url = 'foo(/)?'

But the string happens to start with a forward slash.


--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 30.07.2009 05:18:14 von Daniel Kolbo

b wrote:
> On 07/29/2009 07:48 PM, Daniel Kolbo wrote:
>>
>> code works (no match) for me too on php 5.2.6 build date May 2 2008
>> 18:01:20 with dumbdows NT.
>>
>> preg_match fails but for a reason other than what I think you may be
>> expecting. It fails b/c of the first forwards slash in $url. The regex
>> engine doesn't even get past the second character let alone reaching the
>> end of line anchor.
>
> The forward slash shouldn't be an issue as the delimiter is '%'. The
> full pattern is:
>
> %^/foo/?$%U
>
>
>> Also, your code works (no match) with this first forward slash removed:
>> $url = 'foo(/)?'
>
> But the string happens to start with a forward slash.
>
>
i am not talking about the delimiter
your pattern is:
%^/foo/?$%U
your test string is:
'foo/bar'

the first character of your pattern is a "/" and your first character of
your test string is an "f". They do not match. The regex engine stops
after checking the first character. This has nothing to do with
greediness or end of line anchors, but only with the first character
comparisons.

maybe what you wanted for your test string was
'/foo/bar'

This test string would then require your end of line anchor. Because the
end of line character does not match the "b" the engine stops. No match.

This is consistent with the findings of others who replied to you.

Perhaps your regex engine has a different syntax for anchors. For
example if your engine was seeing the carrot as a an exclusion operator
rather than being a beginning of line anchor and it was also, idk,
ignoring the dollar sign as your end of line anchor then you would get a
match. But otherwise I would recommend you copy/paste the example you
provided and confirm that you still get a match. Then i would confirm
your regex engine's anchor syntax. Then, recompile your software....
dK
`

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 30.07.2009 05:45:28 von B

On 07/29/2009 11:18 PM, Daniel Kolbo wrote:
> b wrote:
>> On 07/29/2009 07:48 PM, Daniel Kolbo wrote:
>>> code works (no match) for me too on php 5.2.6 build date May 2 2008
>>> 18:01:20 with dumbdows NT.
>>>
>>> preg_match fails but for a reason other than what I think you may be
>>> expecting. It fails b/c of the first forwards slash in $url. The regex
>>> engine doesn't even get past the second character let alone reaching the
>>> end of line anchor.
>> The forward slash shouldn't be an issue as the delimiter is '%'. The
>> full pattern is:
>>
>> %^/foo/?$%U
>>
>>
>>> Also, your code works (no match) with this first forward slash removed:
>>> $url = 'foo(/)?'
>> But the string happens to start with a forward slash.
>>
>>
> i am not talking about the delimiter
> your pattern is:
> %^/foo/?$%U
> your test string is:
> 'foo/bar'

AAARRRGGHHHH! Sorry, that's a typo! It should be:

$test = '/foo/bar';

I guess that explains a lot. For the record, I had to type that in
because this latest version of Thunderbird crashes whenever I paste into
it. (note to self: downgrade that, stat!)





--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 30.07.2009 18:33:49 von Ben Dunlap

>>>> echo (preg_match($pattern, $test) != false)
>>
>> The " != false " here is redundant.
>
> Understood. But what you think is redundancy is, to me, clarity in
> programming. I happen to think that boolean tests shouldn't ride on
> whether or not an array returned from a function is empty or not (or a
> freaking boolean). If what I'm looking for is a "false" then that's what
> I'll test for.

Fair enough, but in that case I think you want "!== false". The expression you
have -- "($x != false)" -- will be true whether $x is 0, NULL, an empty string,
an empty array, or actually FALSE.

But "$x !== false" will only be true in the last case.

Ben

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Re: preg_match too greedy

am 30.07.2009 18:36:53 von Ben Dunlap

Ben Dunlap wrote:
> have -- "($x != false)" -- will be true whether $x is 0, NULL, an empty string,
[8<]
> But "$x !== false" will only be true in the last case.

Sorry, replace "be true" with "be false" above.

-Ben

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

RE: preg_match too greedy

am 31.07.2009 12:51:23 von M.Ford

> -----Original Message-----
> From: b [mailto:php@logi.ca]
> Sent: 30 July 2009 03:17
>=20
>=20
> >
> >>> echo (preg_match($pattern, $test) !=3D false)
> >
> > The " !=3D false " here is redundant.
>=20
> Understood. But what you think is redundancy is, to me, clarity in
> programming. I happen to think that boolean tests shouldn't ride on
> whether or not an array returned from a function is empty or not (or
> a
> freaking boolean). If what I'm looking for is a "false" then that's
> what
> I'll test for.

Well, then, by that logic you should be testing separately for ===3DFAL=
SE and ===3D0, since the former means an error occurred, whilst the lat=
ter means the pattern was ok but didn't match. If the pattern finds a matc=
h, the return value is 1 (not TRUE).


Cheers!

Mike
--=20
Mike Ford,
Electronic Information Developer, Libraries and Learning Innovation,
Leeds Metropolitan University, C507, Civic Quarter Campus,=20
Woodhouse Lane, LEEDS,=A0 LS1 3HE,=A0 United Kingdom=20
Email: m.ford@leedsmet.ac.uk=20
Tel: +44 113 812 4730





To view the terms under which this email is distributed, please go to http:=
//disclaimer.leedsmet.ac.uk/email.htm

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php