0

I had a regex that detects when a string IS NOT the given pattern:

/\A((?!.*(www|http|@|\.com\b|\.net\b|\.de\b|\.info\b)).*)$/m

It means that strings like "hi you at www.test.com" is FALSE But now I would liket to allow one URL: www.example.com.

It means:

" this is a test" > TRUE

"this is a test www.example.com" > TRUE

"this is a test example.com this" > TRUE

"this is a test www.test.com this" > FALSE

"this is a test test.com this" > FALSE

"this is a test test.com this www.example.com " > FALSE (false because one forbiden URL is present)

It seems I need to include an AND operator, I think it is:

(?=.*PATTERN)

but unfortunately I couldn't make it work.

ps: I know that this regex that detects urls is not perfect at all, but because my requirements it is bettern than nothing.

Thanks !

Edit: My regex is located in a validator:

def self.validates_is_url_and_email_free(*attr_name)
    validates_format_of attr_name, {:with => /\A((?!.*(www|http|@|\.com\b|\.net\b|\.de\b|\.info\b)).*)$/m, :message => I18n.t(:not_url_email)}
end
ratamaster
  • 169
  • 1
  • 1
  • 12
  • 1
    What are you doing with this match? Why not extract the URI and then do a secondary operation on it? `gsub` and `scan` might help. It seems odd you're using a negative assertion `?!` when you want a positive. – tadman Nov 18 '12 at 21:48
  • possible duplicate of [What's a good way to validate links (urls) in rails 3?](http://stackoverflow.com/questions/7167895/whats-a-good-way-to-validate-links-urls-in-rails-3) -- there are some good ideas there that don't involve rails as well. – Mark Thomas Nov 19 '12 at 01:21

1 Answers1

1

In this case using two separate expressions might be the solution:

OKAY_EXPR = /example\.com/
BANNED_EXPR = /.../ # Existing expression

if (string.match(OKAY_EXPR) and !string.match(BANNED_EXPR))
  # ...
end

It's not clear what you're doing here, but that does seem to be an extremely restrictive set of TLDs. There are literally thousands of valid TLDs which might need to be processed.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • I have added more details in edit section, I don't know how put your code in my :with, if it is possible. thanks ! – ratamaster Nov 19 '12 at 01:12
  • That's a Rails 2.x style validation. Rails 3 has a new syntax: `validates ..., :format => { :with => /.../ }` to do this. In any case, you can always write your own validation routine that does whatever you want and avoid having to write a very complicated regular expression that does it all in one shot. It is possible to express it with some tricky look-ahead negative assertions, but it would end up being almost unreadable line-noise. – tadman Nov 19 '12 at 01:35
  • Yes, I'm using rails 2. Could you show me an example how white this validation routine ? – ratamaster Nov 19 '12 at 02:22
  • 1
    `validate :method_name` will trigger a call to `method_name` during the validations. Your method can then do whatever tests it needs, inject any errors using `errors.add`, and if there's a failure, return `false` to stop the save chain. More examples in [the documentation](http://apidock.com/rails/ActiveRecord/Validations/ClassMethods/validate). – tadman Nov 19 '12 at 16:09