0

I can't seem to get Regular Expressions right whenever I need to use them ...

Given a string like this one:

$string = 'text here [download="PDC" type="A"] and the text continues [download="PDS" type="B"] and more text yet again, more shotcodes might exist ...';

I need to print the "text here" part, then execute a mysql query based on the variables "PDC" and "A", then print the rest of the string... (repeating all again if more [download] exist in the string).

So far I have the following regex

$regex = '/(.*?)[download="(.*?)" type="(.*?)"](.*?)/';
preg_match($regex,$string,$res);
print_r($res);

But this is only capturing the following:

Array ( [0] => 111111 [1] => 111111 [2] => ) 

I'm using preg_match() ... should I use preg_match_all() instead? Anyway ... the regex is surely wrong... any help ?

9
  • 1
    [ opens character class, and ] finishes it. Such characters with meaning need to be either escaped or put into a QE block in PCRE regex. Commented Jan 5, 2013 at 23:58
  • I'm sorry. I'm not following you ... Commented Jan 5, 2013 at 23:59
  • Should it be $regex = '/(.*?)[download="(.*?)" tipo="(.*?)"](.*?)/'; ? Commented Jan 6, 2013 at 0:00
  • Whas a typo when I translated to make the question ... should be read "type" Commented Jan 6, 2013 at 0:01
  • Yes, those who speak some espagnol should know that typo "tipo" ;) Commented Jan 6, 2013 at 0:03

2 Answers 2

2

[ opens character class, and ] finishes it. Such characters with meaning need to be either escaped or put into a QE block in PCRE regex.

/(.*?)\Q[download="\E(.*?)" type="(.*?)"](.*?)/
      ##^          ##         ^-- you were looking for "tipo"
        |
  this character needs to be taken literal, hence the \Q....\E around it
                                                      ##    ##
Sign up to request clarification or add additional context in comments.

4 Comments

Much better now thanks @hakre! But still not complete. I'm getting: Array ( [0] => text here [download="PDC" type="A"] [1] => text here [2] => PDC [3] => A [4] => ) ... the [0] part should only be the "text here" and [4] should have the rest of the string ...
Well, you only need to re-assing with that. It's better done afterwards because [0] is always the full match. If you need to change that with the regex this can become overkill (and is normally not done that way). Just process the return array into a new array and use the new array with the indexes you need to have.
A bit screwed over here :| the last (.*?) group is not picking up anything... in the print_r($result) the last position is always empty I don't know why. Can you take a peak here afonsogomes.com/teste.php ? Please please please!
Fixed it! Posting my answer later on. thanks for the regex you gave me mate! Ended up being the one I used.
1

Try it with with "little" one

/(?P<before>(?:(?!\[download="[^"]*" type="[^"]*"\]).)*)\[download="(?P<download>[^"]*)" type="(?P<type>[^"]*)"\](?P<after>(?:(?!\[download="[^"]*" type="[^"]*"\]).)*)/

It will provide you the keys before, after, download and type in the matches result.

Test it here: http://www.regex101.com/r/mF2vN5

2 Comments

I was using gskinner.com/RegExr/ to test my expressions ... that one is way better for noobs at regex like me! Instant fave! Going to test it right now.
@hakre : the link provides some nice explanations, therefore js is used

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.