0

Im trying to get a part of string doing regex. For eg.

$input = "This is a 'wonderful' day except i am 'stuck' here"

I want to get all characters between two 's.

for this i'm using

preg_match('~\'(.*?)\'~', $input, $output);

but the result i'm getting is only wonderful in $output[0]

what i'm doing wrong? how to get the second part i.e. stuck in this example?

EDIT: I asked this question after checking $output[1]. 'stuck' is not there!

also apart from testing it from my program, i also tried an online regex tester. here's the result:

http://s30.postimg.org/g6dj5xvmp/Selection_009.png

4
  • Kind'a guessing here (never used php), but I think your version will work if you just add the global flag after the last '~', i.e. ~\'(.*?)\'~g and remove the last ')' which I guess was a typo (or it wouldn't have worked at all). (Also, escaping the ' aren't necessary.) Commented Jan 17, 2014 at 13:09
  • hey thanks for pointing out ')' was a typo.. Commented Jan 17, 2014 at 13:12
  • @ClasG: the single quotes have to be escaped here, because the OP's pattern string is delimited by single quotes... and PHP's implementation of the PCRE doesn't have a global flag, but there is a preg_match_all function which does the same thing Commented Jan 17, 2014 at 13:13
  • @EliasVanOotegem: OK, thanks for clearing that up. Commented Jan 17, 2014 at 13:20

2 Answers 2

2

This is really quite simple. You're using preg_match, which attempts to find one occurance of a given pattern, to find all matches use preg_match_all.
Both work in the same way: the $matches array will have the full pattern-match assigned to index 0 (including the quotes), and the group(s) will be assigned to all subsequent indexes (in this case $matches[0] will contain the chars inside the quotes). The difference is that preg_match_all will assign arrays to the aforementioned indexes, listing each match for the pattern.

preg_match("/'([^]+)'/", $input, $matches);
var_dump($matches);

will give an array like this:

array(
    "'wonderful'",    //because the pattern mentions the ' chars
    "wonderful"       //because I'm grouping the chars inside the '
);

Whereas this code:

preg_match_all("/'([^']+)'/", $input, $matches));

Gives you:

array (
   //array of full matches, including the quotes
   array (
       '\'wonderful\'',
       '\'stuck\'',
   ),
   //array with groups
   array (
       'wonderful',
       'stuck',
   ),
);

As you can see on this live example

I've simplified your expression a little, because you're interested in what's "delimited" by single quotes, hence I match and group every non ' that follows a single quote and that is, in turn followed by another single quote. Thus, the char-class you want to match is simply [^']... anything except '.
A possiple micro-optimization you could make to this suggested pattern would be to use a possessive quantifier ++, which is similar to {1,}. Or, if you want to match an empty string if '' is found, you could use *+. so

if (preg_match_all("/'([^']++)'/", $subject, $matches))
    var_dump($matches);

Should do the trick

Sign up to request clarification or add additional context in comments.

2 Comments

@singhshivam: Yes... I explained why preg_match doesn't match all occurances of a given patter, and that is why you should use preg_match_all. I also suggested changing your pattern a little, because as it now stands this '' string will leave you with an empty match
thanks Elias i got it. your answer should have worked for me first time itself but i made some stupid mistake. Anyways thanks a lot for explaining me in such details! :)
2

Do like this

<?php
$str = "This is a 'wonderful' day except i am 'stuck' here";
preg_match_all("/'(.*?)'/", $str, $matches);
print_r($matches[1]);

OUTPUT :

Array
(
    [0] => wonderful
    [1] => stuck
)

2 Comments

@singhshivam, What is your expected output ? I don't see any difference in the question btw. See the demo eval.in/91036
its strange, its working fine on eval, even my complete code shows the correct result. But not working on my program. anyways im sure now the problem here. Thanks a lot for your help! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.