views:

73

answers:

7

How do I say, in regular expressions:

Any portion of a string beginning with a capital letter, containing at least one space character, not containing the string
" _ " (space underscore space), and ending with the string "!!!" (without the quotes)?

I am having trouble with the "not containing" part.

Here is what I have so far:

[A-Z].* .*!!!

How do I modify this to also specify "Not containing ' _ '"?

It does not need to be the specific string " _ ". How can I say "not containing" ANY string? For instance not containing "dog"?

Edit: I'd like the solution to be compatible with Php's "preg_replace"

Edit: Examples:

Examples for " _ ":

Abc xyz!!! <---Matches

Hello World!!! <---Matches

Has _ Space Underscore Space!!! <--- Does Not Match

Examples for "dog":

What a dog!!! <--- Does not match, (contains "dog")

Hello World!!! <--- Matches

+1  A: 

Any possible regex for this would be probably much more complicated than two regexes. One like yours: [A-Z].* .*!!! and the second applied on matched strings and checking whether _ is contained.

eumiro
Unfortunately, I need to "capture" the matching portion of the string, so I require a single regex for it.
Joshua
A: 

Start with Any capital; have an optional string of everything except an underscore, a space, and then the everything except underscore again, followed by three exclamation marks.

[A-Z][^_]*[ ][^_]*!!!
Thomas
Will not match `Abc_d ef!!!`
Benoit
How would I apply this in the case of the "dog" example, in my edit above?
Joshua
A: 

There is a nice little program in which you can built your regex together with testing it.

http://software.marioschneider-online.de/?C%23%3A_RegEx_Test

TEmp69
This is not really an answer to Joshua's question, and is therefor (IMO) better suited as a comment.
Bart Kiers
A: 

First test your string for any occurance of " _ ", since that is a no match. Then check for what you want.

That's what I would do instead of spending a lot of time trying to figure out one regular expression for it.

Here's a nice site for testing your expressions: Nregex

Edit: I read some more on your question and see that my answer wasn't really good, so here's another attempt. A modification of one of the expressions above:

[A-Z](?! _ )(\w(?! _ ))* (\w(?! _ ))*!!!
Fredrik Norlin
+1  A: 

The x(?!y) expression matches x only if it is not immediately followed by y. So, this seems to be the thing you want:

[A-Z](?!%s)(.(?!%s))* (.(?!%s))*!!!

Where %s is your forbidden string.

atomizer
A: 
Eamon Nerbonne
A: 

I used to resolve it via grep's -v option (if I'm on Linux and/or can use grep).

So search for something, then skip the uninteresting parts.

grep something <INPUT> | grep -v uninteresting

Without grep (damn windows, without admin rights) but with Vim:

vim -c "v/i'm searching for this/d" -c "g/and don't need this/d" -c "w checkoutput" <INPUT>

(This opens , then deletes every line what does not match what you need, then deletes every line, what you does not need, then save the results as checkoutput. Which you should check.)

HTH

Zsolt Botykai