views:

99

answers:

7

I found a regex pattern for PHP that does the exact OPPOSITE of what I'm needing, and I'm wondering how I can reverse it?

Let's say I have the following text: Item_154 ($12)

This pattern /\((.*?)\)/ gets what's inside the parenthesis, but I need to get "Item_154" and cut out what's in parenthesis and the space before the parenthesis.

Anybody know how I can do that?

Regex is above my head apparently...

+4  A: 
/^([^( ]*)/

Match everything from the start of the string until the first space or (.

If the item you need to match can have spaces in it, and you only want to get rid of whitespace immediately before the parenthetical, then you can use this instead:

/^([^(]*?)\s*\(/
Amber
perfect! I wish there was some resource online that explained regex in simple damn english... Everywhere I've looked to try to learn it is so complicated and hard to understand.
Josh
Josh, www.regular-expressions.info has a good series of tutorials and reference guides.
Peter Boughton
Nice! Thanks for that...
Josh
+1  A: 

/(.*)\(.*\)/

What is not in () will now be your 1st match :)

Killer_X
That won't strip the whitespace.
Amber
This one works too, but it seems to keep that space between what I need and the parenthesis... Thanks though.
Josh
+2  A: 

The following will match anything that looks like text (...) but returns just the text part in the match.

\w+(?=\s*\([^)]*\))


Explanation:
The \w includes alphanumeric and underscore, with + saying match one or more.
The (?= ) group is positive lookahead, saying "confirm this exists but don't match it".
Then we have \s for whitespace, and * saying zero or more.
The \( and \) matches literal ( and ) characters (since its normally a special chat).
The [^)] is anything non-) character, and again * is zero or more.

Hopefully all makes sense?

Peter Boughton
Haha, it seems there are a multitude of ways to do the same thing with regex, eh?
Josh
Yep. Although all these answers are doing slightly different things - some of which would manifest with different input content. Could be a fun experiment for you to try changing your input text to see how the different answers here respond. :)
Peter Boughton
I have... so far yours and Amber's are the two that stay totally consistent with different input text. However, I chose Ambers answer as she replied first (and it's a little bit shorter)Thanks a ton dude!
Josh
For example, this one would fail with `item-154 (stuff)` whilst others would accept that. However, others would capture the entire of `stuff and item_154 ()` whilst this would ignore the `stuff and` part. And so on.
Peter Boughton
Ah, I didn't test without an underscore... All the item numbers use underscores rather than hyphens, so I guess I didn't even think to try that.
Josh
Yeah, it's easy to add if you need to include it (changing `\w` to `[\w-]` will do it) but if this is a function call, odds are any `-` would be a minus sign not part of the name. The important thing with regex is to know what you want to match and what you want to exclude, and make sure your expression is strict enough to not match incorrectly, but also flexible enough to not need changing all the time. :)
Peter Boughton
A: 
<?php
$string  = 'Item_154 ($12)';
$pattern = '/(.*)\(.*?\)/';

preg_match($pattern, $string, $matches);

var_dump($matches[1]);
?>

Should get you Item_154

Till
+1  A: 

One site that really helped me was http://gskinner.com/RegExr/

It'll let you build a regex and then paste in some sample targets/text to test it against, highlighting matches. All of the possible regex components are listed on the right with (essentially) a tooltip describing the function.

xtremerunnerars
A: 

The following regex works for your string as a replacement if that helps? :-

\s*\(.*?\)

Here's an explanation of what's it doing...

Whitespace, any number of repetitions - \s*

Literal - \(

Any character, any number of repetitions, as few as possible - .*?

Literal - \)

I've found Expresso (http://www.ultrapico.com/) is the best way of learning/working out regular expressions.

HTH

Andy Robinson
Those are *not* literal parentheses in PHP regex.
Peter Boughton
A: 

Here is a one-shot to do the whole thing

$text = 'Item_154 ($12)';
$text = preg_replace('/([^\s]*)\s(\()[^)]*(\))/', $1$2$3, $text);
var_dump($text);
//Outputs: Item_154()

Keep in mind that using any PCRE functions involves a fair amount of overhead, so if you are using something like this in a long loop and the text is simple, you could probably do something like this with substr/strpos and then concat the parens on to the end since you know that they should be empty anyway.

That said, if you are looking to learn REGEXs and be productive with them, I would suggest checking out: http://rexv.org I've found the PCRE tool there to very useful, though it can be quirky in certain ways. In particular, any examples that you work with there should only use single quotes if possible, as it doesn't work with double quotes correctly.

Also, to really get a grip on how to use regexs, I would check out Mastering Regular Expressions by Jeffrey Friedl ISBN-13:978-0596528126 Since you are using PHP, I would try to get the 3rd Edition since it has a section specifically on PHP PCRE. Just make sure to read the first 6 chapters first since they give you the foundation needed to work with the material in that particular chapter. If you see the 2nd Edition on the cheap somewhere, that pretty much the same core material, so it would be a good buy as well.

tsgrasser