Log in

View Full Version : Regular expression question - any number of spaces



CrazyChop
03-22-2009, 06:00 AM
Hi all, currently I am working with this pattern



$pattern = '/<!--' . $tagName . '\\s-->/';


This matches <!--example --> but not <!-- example -->

How should I adjust the regular expression so that it will match <!-- example --> as well as



<!-- example -->

JasonDFR
03-22-2009, 08:54 AM
This was my first attempt. It works, but allows for unequal spaces on either side of tagname. 0 on one side and 1 on the other will match:


'/^(<!\-\-)\s?' . $tagname . '\s?(\-\->)$/'

My second attempt will force the tagname to either be surrounded by one space or no spaces, but looks a bit sloppy. I think there is another way to write it, but I couldn't figure it out. Hopefully someone here knows how because I would like to know too.


'/^(<!\-\-)(' . $tagname . '| ' . $tagname . ' )(\-\->)$/'


<?php

$tagname = 'tagname';
$correct = '<!-- tagname -->';
$pattern = '/^(<!\-\-)\s?' . $tagname . '\s?(\-\->)$/';
//$pattern = '/^(<!\-\-)(' . $tagname . '| ' . $tagname . ' )(\-\->)$/';

if (preg_match($pattern, $correct))
echo 'Matched';
else
echo 'Did not match';

exit;

techietim
03-22-2009, 01:05 PM
This might seem cleaner:


<?php
$string = 'Hello world <!-- example --> this is a test';
preg_match('/<!-- *(example) *-->/', $string, $matches);
print_r($matches);

JasonDFR
03-22-2009, 04:32 PM
How should I adjust the regular expression so that it will match <!-- example --> as well as



<!-- example -->


To add to my first reply, if you want to allow any number of spaces on either side of $tagname, you can use * in place of the ? in this regex:


'/^(<!\-\-)\s?' . $tagname . '\s?(\-\->)$/'
'/^(<!\-\-)\s*' . $tagname . '\s*(\-\->)$/'

I think there is a clean way to make sure that the same number of spaces exists on either side of $tagname as well, but again, I haven't been able to figure it out.

techietim
03-22-2009, 04:36 PM
@Jason

That's called back referencing, and you'd do it like this:


<?php
$string = 'Hello world <!-- example --> this is a test';
preg_match('/<!--( )*(example)\1-->/', $string, $matches);
print_r($matches);

JasonDFR
03-22-2009, 04:48 PM
Thanks Tim. I have been reading a bit about that too, but couldn't get one working just right.

Run this code:


<?php
/* $string = 'Hello world <!-- example --> this is a test';
preg_match('/<!--( )*(example)\1-->/', $string, $matches);
print_r($matches); */

$tagname = 'tagname';
$correct = '<!-- tagname -->'; // Different amount of spaces on each side. Still matches.
$pattern = '/<!--( )*(' . $tagname . ')\1-->/';
//$pattern = '/<!-- *(' . $tagname . ') *-->/';
//$pattern = '/^(<!\-\-)\s?' . $tagname . '\s?(\-\->)$/';
//$pattern = '/^(<!\-\-)(' . $tagname . '| ' . $tagname . ' )(\-\->)$/';

if (preg_match($pattern, $correct))
echo 'Matched';
else
echo 'Did not match';

exit;

Also, in what situation is it a good to add $matches and return the array? In the last post you made it results in 3 keys. The first two are empty and the third's value is 'example'.

Thanks Tim. PS: Look at my directory copier class !!! :)

techietim
03-22-2009, 05:13 PM
This should do it:


<?php
/* $string = 'Hello world <!-- example --> this is a test';
preg_match('/<!--( )*(example)\1-->/', $string, $matches);
print_r($matches); */

$tagname = 'tagname';
$correct = '<!-- tagname -->'; // Different amount of spaces on each side. Still matches.
$pattern = '/<!--( *)(' . $tagname . ')\1-->/';
//$pattern = '/<!--( )*(' . $tagname . ')\1-->/';
//$pattern = '/<!-- *(' . $tagname . ') *-->/';
//$pattern = '/^(<!\-\-)\s?' . $tagname . '\s?(\-\->)$/';
//$pattern = '/^(<!\-\-)(' . $tagname . '| ' . $tagname . ' )(\-\->)$/';

if (preg_match($pattern, $correct))
echo 'Matched';
else
echo 'Did not match';

exit;

[0] is the full comment, so it would only be visible if you view the source of the page
[1] contains the number of spaces on both sides
[2] is the comment string

JasonDFR
03-22-2009, 05:27 PM
Very nice. Now this regex is great. However, [1] is still empty?

Hehe about the comment showing up in source only. Same thing happened to me when I was building the original regex. But naturally I overlooked that again.

See ya.

techietim
03-22-2009, 05:31 PM
It's not actually empty, it contains the spaces that are before the comment name.

JasonDFR
03-22-2009, 05:38 PM
Excellent. Thanks.

Mystery spaces are here:


$s = str_replace(' ', 's', $matches[1]);
echo $s;