Jump to content

Another Regex Question


ShadowMage

Recommended Posts

Hey guys, I've got another regex question. I've got the following code:

$test1 = "varchar(20)";$test2 = "date";$test3 = "decimal(10,3)";$regex = '/([a-z]+)[(]*((\d{1,})[,]*(\d{1,})*)*[)]*/';preg_match($regex, $test1, $matches);echo nl2br(print_r($matches, true));preg_match($regex, $test2, $matches);echo nl2br(print_r($matches, true));preg_match($regex, $test3, $matches);echo nl2br(print_r($matches, true));

This does almost what I want. It returns all the information I need but it also returns a match I don't need. It works perfectly for $test2, as the only match it returns (aside from matching the whole string) is "date" which is exactly what I want. However, it returns an extra match for the other two. Here's how the returned arrays look:Array([0] => varchar(20)[1] => varchar[2] => 20 <-- Extra value[3] => 20)Array([0] => decimal(10,3)[1] => decimal[2] => 10,3 <-- Extra value[3] => 10[4] => 3)Now I know it's matching this part of my regex: ((\d{1,})[,]*(\d{1,})*)*But my question is, is there a way to make it so that the match isn't returned in the array? I need to somehow specify that that portion is optional. Using the parens and the * quantifier works but returns this extra match. Is there another way to do this?

Link to comment
Share on other sites

You might be able to escape the outer parenthesis\((\d{1,})[,]*(\d{1,})*\)
That will match them as part of the pattern, though, and that's not what I want. I want to be able to specify that a portion of the string is optional.
Link to comment
Share on other sites

Make it an assertion instead of a matching pattern. Assertions do not get returned, just validated.
How would I do that? I know that this: (?<=[a-z]) will match something preceded by any letter from a thru z. But how would I apply that in this case? I still need to return the stuff inside the parenthesis (if it exists) but not everything together should be returned. For example, with decimal(10,3) I still need to extract the 10 and the 3 but I don't want to get a match on '10,3'.
Link to comment
Share on other sites

I'm not sure if that's possible, but it might be. It sounds like you want an assertion, and inside the assertion you want 2 matches to get passed back. I'm not sure if it will work that way, but take a look through the section in the manual about assertions and see what it says there.

Link to comment
Share on other sites

I'm not sure if that's possible, but it might be.
Dun Dun Dun!The guru doesn't have an answer! :):)
It sounds like you want an assertion, and inside the assertion you want 2 matches to get passed back. I'm not sure if it will work that way, but take a look through the section in the manual about assertions and see what it says there.
You are correct sir. I need to check if that piece exists, if it does, extract the information from it. I'll do some digging, see what I can find. Thanks tho! :)EDIT:After doing some digging, I've come across this:$regex = '/([a-z]+)(?:[(](\d{1,})(?:[,](\d{1,}))?[)])?/';It seems to work perfectly. (?: )? specifies a non-capturing, optional subpattern, yet the subpatterns within this subpattern will still be captured.
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...