Page 1 of 1

Matching double quotes

Posted: Fri Sep 28, 2007 2:25 am
by jbullard
All,

I am having a bit of trouble with a regex. What I need to do is match and opening and closing double quotes with any type of text in between. I have tried several different versions and they all seem to work except that it does not check for opening and closing quotes. It will match any quotes within a string instead of matching a pair and the text in between.

Any help greatly appreciated.
Jason

Posted: Fri Sep 28, 2007 6:36 am
by GeertDD

Code: Select all

/"([^"]*)"/

Posted: Fri Sep 28, 2007 7:07 am
by jbullard
GeertDD,

Thanks for that but it raises the same problem. If there are slashed quotes it will still stop at the slashed quote and then match the next quote instead of matching the start and stop quote. Any other ideas maybe? :D

Thanks,
Jason

Posted: Fri Sep 28, 2007 9:32 am
by GeertDD
Okay, now I get what you mean.

Code: Select all

/"((?:[^\\"]++|\\.)*)"/

Posted: Fri Sep 28, 2007 5:37 pm
by stereofrog
I don't think this would work, GeertDD.

jbullard, try this pattern

Code: Select all

'/"(\\\\.|[^"])*"/'

Posted: Sat Sep 29, 2007 12:27 am
by GeertDD
Uh, mine works and yours doesn't, stereofrog. Have a look at it again.

Code: Select all

$str = 'Quote: "Spend \"more\", buy less".';


// GeertDD:
preg_match_all('/"((?:[^\\"]++|\\.)*)"/', $str, $matches);

/*
$matches = Array
(
    [0] => Array
        (
            [0] => "Spend \"more\", buy less"
        )

    [1] => Array
        (
            [0] => Spend \"more\", buy less
        )

)
*/


// stereofrog:
preg_match_all('/"(\\\\.|[^"])*"/', $str, $matches);

/*
$matches = Array
(
    [0] => Array
        (
            [0] => "Spend \"
            [1] => ", buy less"
        )

    [1] => Array
        (
            [0] => \
            [1] => s
        )

)
*/

Posted: Sat Sep 29, 2007 3:14 am
by stereofrog
Try running your example once again, GeertDD. ;)

Posted: Sat Sep 29, 2007 5:05 am
by GeertDD
Okay, I see now. Mine worked because my little selfmade regex test app applied addslashes() to the posted regex. How bad. :wink:

So mine really only works after adding the slashes manually. Try this:

Code: Select all

/"((?:[^\\\\"]++|\\\\.)*)"/
And yours does work too, stereofrog. I'd just make the parentheses non-capturing.

Posted: Sat Sep 29, 2007 8:00 am
by jbullard
Thanks for the help guys. However, I ended taking your first example and adding stuff I already had which works perfectly with or without slashes.

This is a double quoted string with anything in between.

Code: Select all

/"([^"].*)"/

And this one is for single quoted strins with anything in between.

Code: Select all

/\'([^\'].*)\'/

Okay so I only added the dot after ], but hey, it works right. :D

Now, here is another problem. Let's say I want to match a specific string inside of another string. So, I will say this:

Code: Select all

$mystring = "Welcome to this place";
Now, I know that I can use a regex to just match the word "is"; however, how do I prevent the following regex from matching "is" in "this".

Code: Select all

$regex = '(is)';
Again, I have tried many different parameters and it always seems to match "is" in "this".

Posted: Sat Sep 29, 2007 10:07 am
by GeertDD
jbullard wrote:This is a double quoted string with anything in between.

Code: Select all

/"([^"].*)"/
Note that that regex is almost the same as

Code: Select all

/".*"/
Your negated character class will match only the first character after the opening quote. The .* part is applied to the rest in a greedy way.

Code: Select all

$mystring = "Welcome to this place";
Now, I know that I can use a regex to just match the word "is"; however, how do I prevent the following regex from matching "is" in "this".

Code: Select all

$regex = '(is)';
Again, I have tried many different parameters and it always seems to match "is" in "this".
You could use \b (word boundary) around the word.

Code: Select all

/\bis\b/

Posted: Sat Sep 29, 2007 11:56 am
by stereofrog
jbullard wrote:
Okay so I only added the dot after ], but hey, it works right. :D
It actually doesn't. Study the output from the following example and try to find out why your expression doesn't print the correct result

Code: Select all

$str = ' begin "one" and "two" and "" and "esc " ape" end ';

$re = '/"([^"].*)"/';
preg_match_all($re, $str, $m);
print_r($m);

$re = '/"(\\\\.|[^"])*"/';
preg_match_all($re, $str, $m);
print_r($m);