Matching anything but....

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

Moderator: General Moderators

Post Reply
User avatar
kendall
Forum Regular
Posts: 852
Joined: Tue Jul 30, 2002 10:21 am
Location: Trinidad, West Indies
Contact:

Matching anything but....

Post by kendall »

Hey guys I'm trying to create a reg expression that will match anything thats "NOT" in the pattern

thus if i wanted to match anything but "delete" in "deleteaddress" i would match address

This is all i have

Code: Select all

/[^(delete)]/
Why won't the () group the pattern?
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Matching anything but....

Post by AbraCadaver »

The [ and ] contain character classes. You can't use it that way. Here is something that may work:

Code: Select all

/(.*)delete(.*)/
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
kendall
Forum Regular
Posts: 852
Joined: Tue Jul 30, 2002 10:21 am
Location: Trinidad, West Indies
Contact:

Re: Matching anything but....

Post by kendall »

AbraCadaver wrote:The [ and ] contain character classes. You can't use it that way. Here is something that may work:

Code: Select all

/(.*)delete(.*)/
NOT QUITE....this will match delete and not address I need it to match address an NOT delete thus a ('delete_address').replace() would give me "delete" and NOT "address"
User avatar
kendall
Forum Regular
Posts: 852
Joined: Tue Jul 30, 2002 10:21 am
Location: Trinidad, West Indies
Contact:

Re: Matching anything but....

Post by kendall »

This does it

Code: Select all

[^delete](.*)
but

Code: Select all

('deleteevents').replace(/[^delete](.*)/,"")
gives me back deletee

Why the extra e?
User avatar
kendall
Forum Regular
Posts: 852
Joined: Tue Jul 30, 2002 10:21 am
Location: Trinidad, West Indies
Contact:

Re: Matching anything but....[SOLVED]

Post by kendall »

Code: Select all

var reg = /([^delete].*)/
this does....

('deleteevent').replace(reg,"") and ('delete_photo').replace(reg,"") gives me delete

can anyone see where this would NOT work where the "delete" is in front?
User avatar
ridgerunner
Forum Contributor
Posts: 214
Joined: Sun Jul 05, 2009 10:39 pm
Location: SLC, UT

Re: Matching anything but....

Post by ridgerunner »

Sorry, but as AbraCadaver said: [^delete] does not do what you think it does! A character class (i.e. anything between square brackets []), always matches exactly one character and one character only!

The regex engine reads your [^delete] expression as: "match exactly one character that is NOT a 'd' or an 'e' or an 'l' or an 'e' or a 't' or an 'e'."

So [^delete] is exactly the same as [^delt] which is the same as [^tled], and [^letd], and...
User avatar
kendall
Forum Regular
Posts: 852
Joined: Tue Jul 30, 2002 10:21 am
Location: Trinidad, West Indies
Contact:

Re: Matching anything but....

Post by kendall »

Oo..ok well from the reference its the only way i can "NOT" how else can I "NOT"? I want to replace anything that is NOT "delete|add|edit|rename" at the begining of the string
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: Matching anything but....

Post by AbraCadaver »

OK, that's more information. You need a negative lookbehind. Something like this might work:

Code: Select all

/((?<!delete|add|edit|rename).*)/
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
User avatar
kendall
Forum Regular
Posts: 852
Joined: Tue Jul 30, 2002 10:21 am
Location: Trinidad, West Indies
Contact:

Re: Matching anything but....

Post by kendall »

AbraCadaver wrote:OK, that's more information. You need a negative lookbehind. Something like this might work:

Code: Select all

/((?<!delete|add|edit|rename).*)/
I get some kind of error when i add the ">"

from a reference snippet i tried .(?=delete) which to me means match anything after "delete" so then why "deleteevents" wouldn't work?
User avatar
ridgerunner
Forum Contributor
Posts: 214
Joined: Sun Jul 05, 2009 10:39 pm
Location: SLC, UT

Re: Matching anything but....

Post by ridgerunner »

AbraCadaver wrote:OK, that's more information. You need a negative lookbehind. Something like this might work:

Code: Select all

/((?<!delete|add|edit|rename).*)/
Actually, this regex does not behave like you think. The negative lookbehind is asserted only once at the beginning of the test string (which will always be true), but is never checked again. The dot star then happily marches though the entire string matching everything in its wake. This regex matches every string in the universe! And as it turns out, kendall is using JavaScript which doesn't have lookbehind...
kendall wrote:... I get some kind of error when i add the ">" ...
You are using JavaScript yes? Unfortunately the JavaScript regex engine does not handle negative or positive lookbehind syntax - i.e. neither (?<!...) nor (?<=...) However, JavaScript does handle both positive and negative lookahead syntax. But this is not what you need here...
kendall wrote:... I want to replace anything that is NOT "delete|add|edit|rename" at the beginning of the string
What do you want to replace it with?

I get the impression (from your previous posts) that you actually want to replace them with nothing and leave the keyword intact. But in any case you need to look at the problem from a different angle (regular expressions are terrible at finding things that don't match). Try, instead to match (and capture) both components then discard what you don't want and keep the rest. See if the following JavaScript snippets shed some light on a better solution:

Code: Select all

// regex to capture the initial keyword in group 1 and the rest in group 2
var RE = /^(delete|add|edit|rename)(.*)/mg;
 
// if you want to keep the keyword and discard the rest, use this
var result = 'deleteevent'.replace(RE, "$1"); // 'delete'
 
// if you want to discard the keyword and keep the rest, use this
var result = 'deleteevent'.replace(RE, "$2"); // 'event'
Hope this helps! :)
User avatar
kendall
Forum Regular
Posts: 852
Joined: Tue Jul 30, 2002 10:21 am
Location: Trinidad, West Indies
Contact:

Re: Matching anything but....

Post by kendall »

wow ok...i have seen the $1 and $2 parameters in code on the web...but i have never seen anything in the references...what does it mean?


thanks :D
User avatar
ridgerunner
Forum Contributor
Posts: 214
Joined: Sun Jul 05, 2009 10:39 pm
Location: SLC, UT

Re: Matching anything but....

Post by ridgerunner »

When you write a regex, anything you place between rounded parentheses () is a group and everything from your subject text that matches in that group is captured into a variable. The first set of rounded parentheses captures into group 1 and the second set of rounded parentheses captures into group 2 and so on. You can access the contents of these variables from within the replace string as $1, $2 etc and from within the regex itself as \1, \2 etc (which are refered to as a backreferences). You can nest these parentheses (so one is a subset of another), and the group number is always determined by counting the left parentheses starting from left to right.

This is a very powerful feature that is very handy!

This is a fundamental capability of regular expressions and I would recommend that you take a look at a good online tutorial to brush up on these basics. (The time you spend will pay for itself many times over.) I would recommend starting here: http://www.regular-expressions.info/
Post Reply