RegEx to tell if a string does not contain a specific character
Asked Answered
B

6

35

Easy question this time.

I'm trying to test whether or not a string does not contain a character using regular expressions. I thought the expression was of the form "[^x]" where x is the character that you don't want to appear, but that doesn't seem to be working.

For example,

Regex.IsMatch("103","[^0]")

and

Regex.IsMatch("103&","[^&]")

both return true (I would expect false).

I started using "[^&]" and thought maybe the & needed to be escaped as \&, but it didn't seem to make a difference.

Ideas? I assume it's something small.

Also, I'm using .NET, so keep that in mind.

Edit1:

I found this, but it doesn't seem to answer the issue I'm having.

Edit2:

I wanted to respond to Kevin and Joel's suggestions. These suggestions would indeed be faster, but they don't accomplish the flexibility I need in this case, so if you found this question through search, definitely look to see if their answers will fit your needs. In my case, the regular expression is getting passed in to a DataTable validation method that loops through each row and verifies that the contents of that row in a specific column matches the RegEx that is getting passed in. Since I'll be reusing this method for several other DataTables that are being validated, I wanted to:

  1. Use Regex to enable the widest range of validations, and
  2. Always look for a positive match (i.e. instead of using !Regex.IsMatch(cell, regexvariable), I wanted to rely on always being able to use Regex.IsMatch(cell, regexvariable) since the majority of DataTables invoking this method will be using the positive match instead of the negative.

Hopefully that helps.

Boycott answered 13/10, 2008 at 19:43 Comment(1)
If you are only checking for the presence of a single character, you can get by much better without regexes. Kevin is right: use .IndexOf() or something simpler. It'll be more readable, clearer, and faster.Lindane
F
54

Your solution is half right. The match you see is for the other characters. What you want to say is something like "hey! I do not want to see this character in the entire string".

In that case you do:

Regex.IsMatch("103","^[^0]*$")
Flocky answered 13/10, 2008 at 19:45 Comment(4)
Thanks! I had also tried "^[^0]$", but gave up on the ^ and $ as it was causing everything to evaluate to false -- just needed that asterisk. Thanks again -- my "two problems" are now back to zero.Boycott
I would guess that !Regex.IsMatch("103","0") would be faster actually.Piraeus
I'm using this, I don't want to see characters ?, [, and ], I tried ^[^?]*$, that worked for ? based on the above example, but when I add the bracket characters it doesn't work... ^[^?[]]*$Melitamelitopol
@SAFX You need to escape the chars [ and ] when used within the set delimiters. So your final regex would be: ^[^\[\]]*$. Hope that helps.Mccormack
A
17

The pattern [^0] will match any character that is not a zero. In both of your examples, the pattern will match the first character ("1"). To test whether the entire string contains no zeros, the pattern should be "^[^0]*$". This reads as follows: Start at the beginning of the string, match an arbitrary number of characters which are not zeros, followed immediately by the end of the string. Any string containing a zero will fail. Any string containing no zeros will pass.

Ammadas answered 13/10, 2008 at 19:53 Comment(0)
K
7

if you are looking for a single character in a string, regex seems like a bit of an overkill. Why not just use .IndexOf or .Contains ?

Kellar answered 13/10, 2008 at 19:46 Comment(1)
This would work, but I'm trying to write a DataTable validator using decorators and I wanted a method that would allow me to extend to other string matches (be it inclusive or exclusive).Boycott
F
4

The first character the parser reaches is "1", which is true for [^0] and also true for [^&], so therefore it will return true in both of those examples.

Fertilizer answered 13/10, 2008 at 19:45 Comment(0)
O
2

You're putting your negation in the wrong place. [^x] will match anything that isn't x. If x is in the string, the string still matches the expression if there are any other characters as well. Instead, you want to match true if x is there, and then negate the result of the function:

Not Regex.IsMatch("103", "0")

Not Regex.IsMatch("103&", "&")

Not that with these simple examples, the normal String.IndexOf() or String.Contains() would be a better choice.

Osmious answered 13/10, 2008 at 19:47 Comment(0)
E
2

I came across this question looking for the same thing but for JavaScript. The expression above did not work in my case, but I came across the below expression which did. (Just in case anybody else looking for a JavaScript solution ends up here too.)

^((?!0).)*$

This construct is called a Negative Lookahead

Edema answered 23/3, 2010 at 20:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.