Matching double quotes

Any questions involving matching text strings to patterns - the pattern is called a "regular expression."

Moderator: General Moderators

Post Reply
jbullard
Forum Newbie
Posts: 3
Joined: Fri Sep 28, 2007 1:53 am

Matching double quotes

Post 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
User avatar
GeertDD
Forum Contributor
Posts: 274
Joined: Sun Oct 22, 2006 1:47 am
Location: Belgium

Post by GeertDD »

Code: Select all

/"([^"]*)"/
jbullard
Forum Newbie
Posts: 3
Joined: Fri Sep 28, 2007 1:53 am

Post 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
User avatar
GeertDD
Forum Contributor
Posts: 274
Joined: Sun Oct 22, 2006 1:47 am
Location: Belgium

Post by GeertDD »

Okay, now I get what you mean.

Code: Select all

/"((?:[^\\"]++|\\.)*)"/
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

I don't think this would work, GeertDD.

jbullard, try this pattern

Code: Select all

'/"(\\\\.|[^"])*"/'
User avatar
GeertDD
Forum Contributor
Posts: 274
Joined: Sun Oct 22, 2006 1:47 am
Location: Belgium

Post 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
        )

)
*/
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post by stereofrog »

Try running your example once again, GeertDD. ;)
User avatar
GeertDD
Forum Contributor
Posts: 274
Joined: Sun Oct 22, 2006 1:47 am
Location: Belgium

Post 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.
jbullard
Forum Newbie
Posts: 3
Joined: Fri Sep 28, 2007 1:53 am

Post 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".
User avatar
GeertDD
Forum Contributor
Posts: 274
Joined: Sun Oct 22, 2006 1:47 am
Location: Belgium

Post 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/
User avatar
stereofrog
Forum Contributor
Posts: 386
Joined: Mon Dec 04, 2006 6:10 am

Post 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);
Post Reply