Regex not select word with character at the end - regex

I have a simple question.
I need a regular expression to match a hexdecimal number without colon at the end.
For example:
0x85af6b9d: 0x00256f8a ;some more interesting code
// dont match 0x85af6b9d: at all, but match 0x00256f8a
My expression for hexdecimal number is 0[xX][0-9A-Fa-f]{1,8}
Version with (?!:) is not possible, because it will just match 0x85af6b9 (because of the {1,8} token)
Using a $ also isn't possible - there can be more numbers than one
Thanks!

Here is one way to do so:
0[xX][0-9A-Fa-f]{1,8}(?![0-9A-Fa-f:])
See the online demo.
We use a negative lookahead to match all hexadecimal numbers without : at the end. Because of {1,8}, it is also necessary to ensure that the entire hexadecimal number is correctly matched. We therefore reuse the character set ([0-9A-Fa-f]) to ensure that the number does not continue.

Related

How to check if word boundary has all zero using regex

I am writing regex to validate contact number. I am using following regex for validation as :
^(?!\b(0)\1+\b)(?!(-))([+]?(\d{1,3})?[\s.-]?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$)
I do not want to match input like "+00 (000) 000-0000" using this regex.
The regex should not match "+00 (000) 000-0000".
I was trying to fix this by using "word boundary should not contains all zero" but not sure how to do it.
Please suggest how to fix this. Any pointer would help.
Thanks
You have whitespaces, (, ), + and - symbols allowed beside digits. So, if you prohibit the string to contain these symbols and 0 digit only, you will achieve the effect you want.
Add the (?![0\s()+-]+$) negative lookahead after ^ so that it could be executed at the very start of the string.
^(?![0\s()+-]+$)(?!-)([+]?(\d{1,3})?[\s.-]?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$)
See the regex demo.
If you want to reject the match if the phone number has all zeroes, you can enforce the presence of a non-zero number using a positive look ahead (?=.*[1-9])
^(?=.*[1-9])(?!-)([+]?(\d{1,3})?[\s.-]?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$)
^^^^^^^^^^^ This ensures the number have at least one non-zero number
Demo

Regex that matches specific letters preceded by a percent sign and does not allow numbers. "%l%m%p"

I'm having trouble writing a regex that matches a pattern like this "%n%m%p" or "%n:%m%p". Only allow specific letters and each letter must have percent sign in front of it. No numbers allowed.
This regex /%(n|m|p)$/ works but allows numbers in between. For example this "%n3%p%m" matches. How do I disallow any numbers.
The regex %(n|m|p) itself matches either %n or %m or %p. That the numbers are allowed between each of the parts is most likely because of your other code.
You can match the whole with this regex
/^(%(n|m|p):{0,1}){0,}$/
Just need to be clear about the exact requirements.
The allowed letters are [nmp]
Each letter has to be preceded by a %
There can be an optional : before %
+ One or more tokens from ^ start to $ end
These requirements won't allow any digit.
^(?::?%[nmp])+$
You can test it at regex101
I can't leave a comment but I can answer, so...
It would help to know what exactly you need from this. Do you need those letters in that order? Do you need exactly 3? Or are you looking for any number of any length with any valid characters in between?
That said, one option if you're matching the entire string is
/^(%[nmp][^\d]*)+$/
which should match any %[nmp] with any character between them that isn't a number. Note though that this will match a single %n for example. If you want to match a specific number i or more than a certain number j, change the + to {i} or {j,} respectively.
As long as it has one of the letters and a percent sign it should
match. Just no numbers
Use the following regex pattern:
%[nmp](?!\d)\b
https://regex101.com/r/CrSnFp/2
(?!\d) - negative lookahead assertion, matches one of the specified characters if it's not followed by a number

regular expression for decimal with fixed total number of digits

Is there a way to write regular expression that will match strings like
(0|[1-9][0-9]*)\.[0-9]+
but with a specified number of numeric characters. for example: for 3 numeric characters it should match "0.12", "12.3" but not match "1.234" or "1.2". I know I can write it something like
(?<![0-9])(([0-9]{1}\.[0-9]{2})|([1-9][0-9]{1})\.[0-9]{1})(?![0-9])
but that becomes quite tedious for large number of digits.
(I know I don't need {1} but it better explains what I'm doing)
^(?=[\d.]{4}$)\d+\.\d+$
You can try this for 3 digits.Can be extended for more.See demo.
https://regex101.com/r/bN8dL3/4
or
\b(?=[\d.]{4}\b)\d+\.\d+\b
If you dont want anchors.
You can match them with adding alternatation:
\b(?:[0-9]\.[0-9]{2}|[1-9][0-9]\.[0-9])\b
Then, you won't need any start/end string/line anchors.
See demo

Regex repetition

I'm trying to perform a regex replacement. Therefor I defined the following expression:
^(?:9903[0]*([0-9]*)){20}$
This Expression should match to
99030000000000000001
99030000000000000011
99030000000000000111
99030000000000001111
99031111111111111111
but not to
9903111111111111111
In fact, the expression above does not work until I either use {1,20} as quantifier or remove it completely. But as I want to check the length of the whole string without knowing the length of [0]* nor the length of the variable, there's something wrong with my expression.
Many thanks for your help in advance.
D
There are multiple things wrong with your initial regex.
The {} part is applied to en entire part between brackets. So your current regex requires that this part:
(?:9903[0]*([0-9]*))
Is repeated 20 times in its entirety, which is not what you want.
Then this part:
[0]*([0-9]*)
Makes little sense, do you want to capture the number after 9903 without the leading zeros? Then require that the capture starts with a non-zero number. [0] is a character class with just one character, equivalent to just 0.
Concluding, I would do it like so:
^9903(?=[0-9]{16}$)0*([1-9][0-9]*)$
Regex101
Edit: I realized later that if it's required to match 99030000000000000000 (get 0 in your capture group) then you need this:
^9903(?=[0-9]{16}$)0*([0-9]+)$
Regex101
You can do that by checking previously the length of the string with a lookahead:
^(?=[0-9]{20}$)99030*[0-9]*
The lookahead (?=...) is a zero-width assertion that checks what follows in the string. Here it is checking there are exactly 20 digits before the end of the string.

Need a simple RegEx to find a number in a single word

I've got the following url route and i'm wanting to make sure that a segment of the route will only accept numbers. as such, i can provide some regex which checks the word.
/page/{currentPage}
so.. can someone give me a regex which matches when the word is a number (any int) greater than 0 (ie. 1 <-> int.max).
/^[1-9][0-9]*$/
Problems with other answers:
/([1-9][0-9]*)/ // Will match -1 and foo1bar
#[1-9]+# // Will not match 10, same problems as the first
[1-9] // Will only match one digit, same problems as first
If you want it greater than 0, use this regex:
/([1-9][0-9]*)/
This'll work as long as the number doesn't have leading zeros (like '03').
However, I recommend just using a simple [0-9]+ regex, and validating the number in your actual site code.
This one would address your specific problem. This expression
/\/page\/(0*[1-9][0-9]*)/ or "Perl-compatible" /\/page\/(0*[1-9]\d*)/
should capture any non-zero number, even 0-filled. And because it doesn't even look for a sign, - after the slash will not fit the pattern.
The problem that I have with eyelidlessness' expression is that, likely you do not already have the number isolated so that ^ and $ would work. You're going to have to do some work to isolate it. But a general solution would not be to assume that the number is all that a string contains, as below.
/(^|[^0-9-])(0*[1-9][0-9]*)([^0-9]|$)/
And the two tail-end groups, you could replace with word boundary marks (\b), if the RE language had those. Failing that you would put them into non-capturing groups, if the language had them, or even lookarounds if it had those--but it would more likely have word boundaries before lookarounds.
Full Perl-compatible version:
/(?<![\d-])(0*[1-9]\d*)\b/
I chose a negative lookbehind instead of a word boundary, because '-' is not a word-character, and so -1 will have a "word boundary" between the '-' and the '1'. And a negative lookbehind will match the beginning of the string--there just can't be a digit character or '-' in front.
You could say that the zero-width assumption ^ is just one of the cases that satisfies the zero-width assumption (?<![\d-]).
string testString = #"/page/100";
string pageNumber = Regex.Match(testString, "/page/([1-9][0-9]*)").Groups[1].Value;
If not matched pageNumber will be ""
While Jeremy's regex isn't perfect (should be tested in context, against leading characters and such), his advice is good: go for a generic, simple regex (eg. if you must use it in Apache's mod_rewrite) but by any means, handle the final redirect in server's code (if you can) and do a real check of parameter's validity there.
Otherwise, I would improve Jeremy's expression with bounds: /\b([1-9][0-9]*)$/
Of course, a regex cannot provide a check against any max int, at best you can control the number of digits: /\b([1-9][0-9]{0,2})$/ for example.
This will match any string such that, if it contains /page/, it must be followed by a number, not consisting of only zeros.
^(?!.*?/page/([0-9]*[^0-9/]|0*/))
(?! ) is a negative look-ahead. It will match an empty string, only if it's contained pattern does not match from the current position.