tags:

views:

85

answers:

2

I work in Ruby, and have to create a single regexp for the following task, as I'm working with someone else's gem that uses this regexp to match fields to be worked on in a text file. I need to match beginning of string, any set of characters, and underscore, then any multi-digit integer that is not 1,2, 9, or 10, and end of string.
I.e., I want the following to match:

foo_4
bar_8
baz_120

BUT NOT:

foo_1
bar_9
baz_10

I tried

/^.+_(^(1|2|9|10))$/

but it did not work as apparently ^ only "negates" characters in brackets, not submatches.

+3  A: 

Outside of a character class the ^ symbol means start of line. I think you want a negative lookahead instead:

/^.+_(?!(?:1|2|9|10)$)\d+$/

See it in action on rubular.

Mark Byers
`^` means start of line, not start of string. `\A` means start of string.
Jörg W Mittag
@Mark: no. `^` **always** means start of line, no matter whether you use the `m` flag to perform multiline matching or not. You can only ignore the difference when you're sure that the string you're matching against has no newlines in it.
Ken Bloom
@Ken Bloom: Sorry, you are right - I check and in Ruby it does always mean start of line (in most other regular expression engines ^ means start of string and I assumed Ruby was the same). I fixed my post. Thanks for being so persistent!
Mark Byers
Shocking truth. I also thought `^` marked the beginning of the string, surprised to know that it actually represents newline.
Chubas
A: 

So, the ending integer has to be multi-digit, right? If that's the case, then you don't need to check for 1, 2, or 9, I would think. I'm trying to find the write expression, but I'm a newby at regular expressions.

Edit: nevermind as by the time I finished this you had edited your post. :)

XstreamINsanity
This is not an answer. It should be a comment to the question.
Mark Byers
I understand, but it won't let me comment on the question. I think it's because my reputation is only at 38 right now. I could be wrong though.
XstreamINsanity
@Xstream, then, perhaps you should spend some time for earning reputation instead of writing comments?
Pavel Shved
I'm trying. I've spent more time than I should on here today researching for work but at the same time trying to help people with their questions so that I can get points for reputation. Sorry if this is an inconvenience to you guys. :(
XstreamINsanity
@XstreamINsanity: Sorry I forgot that there is that reputation limit. I upvoted one of your other answers so that next time you want to ask the OP a question you can write it in a comment. :)
Mark Byers
:) Thanks, I do appreciate it. Now I have to make sure I keep my dumb answers to a minimum as I've been down bumped a few times today. :)
XstreamINsanity