Check string includes integer at the end - ruby-on-rails

I want to check whether the given string includes "test_icon_<integer>". the integer could be 10 or 22 or 32 or 109 or 120.( first integer can't be zero but second and third digits can be zero)
Following strings are not accepted
1."test_icon_<1a>"
2."test_icon_<1.1>"
3. "test_icon_<!#q>"
4. "test_icon_<abced>"
Please help me to solve this.

This regex matches your strings and fails on the bad ones:
test_icon_<[1-9]\d{0,2}>
see demo.
Explain Regex
test_icon_< # 'test_icon_<'
[1-9] # any character of: '1' to '9'
\d{0,2} # digits (0-9) (between 0 and 2 times
# (matching the most amount possible))
> # '>'

This should work for you:
test_icon_<((?!0)\d)\d{0,2}>
Demo with explanation

Following regex should solve your problem:
/test_icon_\<[0-9]+\>/
Hope this helps :)

Related

How can I catch a US phone number with +1 area code regex

I have the following requirement.
I need to validate with Rails that a phone number begins with +1 and is met with exactly 10 digits after this? So far, I have this regex expression.
^+1\d{10}
This is not working and I'm having a bit of trouble trying to tweak this to match exactly what I need. Does anyone have any ideas the validation has to catch this exactly.
+19564321234
etc. Help would be appreciated. Thank you.
You have two problems with your regular expression:
You have not escaped the plus sign, so it reads, "match the beginning of a line, followed by one or more (+) zero-width characters, followed by 10 digits"
You have omitted an end-of-string anchor, so \d{10} will match a string of 10 or more digits
You need to write:
r = /\A\+\d{10}\z/
"+1234567890".match? r #=> true
"1234567890".match? r #=> false
"+1234567890123".match? r #=> false
I've used the beginning-of-string anchor, \A, rather than the beginning-of-line anchor ^. The latter would be in problem only in some extreme cases, such as:
"dog\n+1234567890".match? /^\+\d{10}\z/ #=> true
Start your engine!. To see it tested against several strings one must change the anchors to ^ and $ and add the multiline (/m) modifier.

Define a regex, which matches one digit twice and all others once

As part of a larger regex I would like to match the following restrictions:
The string has 11 digits
All digits are numbers
Within the first 10 digits one number [0-9] (and one only!) must be listed twice
This means the following should match:
12345678914
12235879600
Whereas these should not:
12345678903 -> none of the numbers at digits 1 to 10 appears twice
14427823482 -> one number appears more than twice
72349121762 -> two numbers appear twice
I have tried to use a lookahead, but all I'm managing is that the regex counts a certain digit, i.e.:
(?!.*0\1{2})
That does not do what I need. Is my query even possible with regex?
You can use this kind of pattern:
\A(?=\d{11}\z)(?:(\d)(?!\d*\1\d))*(\d)(?=\d*\2\d)(?:(\d)(?!\d*\3\d))+\d\z
online demo
pattern details:
the idea is to describe string as a duplicate digit surrounded by non duplicate digits.
Finding a duplicate digit is easy with a capture group, a lookahead assertion and a backreference:(\d)(?=\d*\1)
You can use the same pattern to ensure that a digit has no duplicate, but this time with a negative lookahead: (\d)(?!\d*\1)
To not take in account the last digit (digit n°11) in the search of duplicates, you only need to add a digit after the backreference. (\d)(?=\d*\1\d) (in this way you ensure there is at least one digit between the backreference and the end of the string.)
Note that in the present context, what is called a duplicate digit is a digit that is not followed immediatly or later with the same digit. (i.e. in 1234567891 the first 1 is a duplicate digit, but the last 1 is no more a duplicate digit because it is not followed by an other 1)
\A # begining of the string
(?=\d{11}\z) # check the string length (if not needed, remove it)
(?:(\d)(?!\d*\1\d))* # zero or more non duplicate digits
(\d)(?=\d*\2\d) # one duplicate digit
(?:(\d)(?!\d*\3\d))+ # one or more non duplicate digits
\d # the ignored last digit
\z # end of the string
an other way
This time you check the duplicates at the begining of the pattern with lookaheads. One lookahead to ensure there is one duplicate digit, one negative lookahead to ensure there are not two duplicate digits:
\A(?=\d*(\d)(?=\d*\1\d))(?!\d*(\d)(?=\d*\2\d)\d*(\d)(?=\d*\3\d))\d{11}\z
pattern details:
\A
(?= # check if there is one duplicate digit
\d*(\d)(?=\d*\1\d)
)
(?! # check if there are not two duplicate digits
\d*(\d)(?=\d*\2\d) # the first
\d*(\d)(?=\d*\3\d) # the second
)
\d{11}
\z
Note: However it seems that the first way is more efficient.
The code way
You can easily check if your string fit the requirements with array methods:
> mydigs = "12345678913"
=> "12345678913"
> puts (mydigs.split(//).take 10).uniq.size == 9
true
=> nil

iOS regex pattern not working to match numbers

I want to match strings of the forms:
123
.123
1.123
and I am using the following string for my regex
#"^\\d*(?:\\.\\d+)?$"
However, it matches strings of the following forms as well
1.2.3
1..2..3
123...
What's wrong with my regex? I used the ^ and $ because I don't want the string to contain anything other than the number forms mentioned.
EDIT:
I logged what is matched in the string like 78..7 and found that the match location is 0 and length is 0 with a result of "" being matched. Any ideas? Shouldn't the range location be NSNotFound if the length is 0? I suppose the regex expression is fine then and I can just check for !length but that seems like an unnecessary work around.
Try this regex:
^(?<!\.)\d*(\.\d+)?$
I added a negative look-behind assertion that means that no dot is allowed before that numbers. That should fix your problem.
Description
This regex will find valid positive real numbers with or without a decimal point. like 123, .123, 1.123. The expression can be applied against a string where each value tested is on it's own line or find numbers in the middle of a block of text. It will also allow punctuation like periods and commas directly after the number but won't capture them.
(?<=^|\s)\d*\.?\d+(?=[,.;]?(?:\s|$))
Given Input String:
1.2.3
1..2..3
128...
1234
.123
1.123
1...23
1.2.3
123...
I like kittens 345.23, and version 2.3.4 dogs
Matches are:
1234
.123
1.123
345.23
Does this work for you?
#"^\\d*\\.?\\d+$"
Here it is without escaped backslashes:
^\d*\.?\d+$
My best guess is that rekire is right about the $ symbol not working. If that's the case, then the regex does actually match the empty substring at the start of the string, which explains why it says it's found a match of length 0 at location 0, instead of NSNotFound.
This is REGEX match your strings:
[0-9]*(.){0,1}[0-9]+

Identify all numbers that append '#' in Ruby

I have a message(m) say "fixes #1 ~needs verification".
I want to identify all numbers that append '#'. So, i scan the text:
issue = m.scan(/[^\#][0-9]+/)
But issue is empty unless the number after # is two digits or > 9 meaning if the message is "fixes #10 ~needs verification" then my issue is 10.
What am i doing wrong here?
You're negating the character class, so your regex is matching (anything that isn't #) followed by one or more digits. 2-digit numbers fit this, but one-digit numbers prefixed by # do not.
Here's what you should do instead:
issue = m.scan(/#[0-9]+/)
Or (credit to this answer):
issue = m.scan(/#\d+/)
"fixes #1 ~needs #12verification" .scan(/#\d+/) #=> ["#1", "#12"]
Take the square brackets off of the # sign:
issue = m.scan(/^#[0-9]+/)

Regex - Cost of an Item

What is the regular expression to check a cost has been provided correctly:
Number must be greater than or equal to 0.01
Number must be less than or equal to 99.99
Possible matches are:
9 | 23.3 | 25.69
Not allowed:
| 2.
Of course, the correct way would be to take the provided string, convert it to a number (catching errors if it's not a parseable number) and then compare that with the valid values.
If it has to be a regex, it's of course possible but ugly:
^(?:[1-9][0-9]?(?:\.[0-9]{1,2})?|0?.0[1-9]|0?.[1-9][0-9]?)$
Explanation:
^ # start of string
(?: # either match
[1-9][0-9]? # a number between 1 and 99
(?:\.[0-9]{1,2})? # optionally followed by a decimal point and up to two digits
| # or
0?.0[1-9] # a number between 0.01 and 0.09 (optionally without leading 0)
| # or
0?.[1-9][0-9]? # a number between 0.1 and 0.99
) # end of alternation
$ # end of string
Of course, in most regex dialects, you can use \d in place of [0-9] without a change in meaning, but I think in this case sticking to the longer version helps readability.
In Ruby, assuming your input string never contains a newline:
if subject =~ /^(?:[1-9][0-9]?(?:\.[0-9]{1,2})?|0?.0[1-9]|0?.[1-9][0-9]?)$/
# Successful match
else
# Match attempt failed
end
Since you care about the number of significant digits, another solution would be to first check if the input looks like a number, and if it passes that test, convert it to a float and check if it's in range.
^(\d{1,2}|\d{0,2}\.\d{1,2})$
would match any number (integer or decimal up to two digits after the decimal point) between 0 and 99.99. Then you just need to check whether the number is >= 0.01. The advantage of this approach is that you can easily extend the range of digits allowed before/after the decimal point if the requirements for valid numbers change, and then adjust the value check accordingly.
I am not sure you need to do this using regular expression why dont you just split the string on '|' into an array and check each element in array is greater than 0.01 and less than 99.99
A solution using a regexp would be hard to maintain since it is a very strange and unintuitive way to solve the problem. It would be hard for anyone reading your code (including yourself in a couple of weeks) to understand what the purpose of the check is.
That said, assuming values 0.00 - 99.99 are valid, the regexp could be
^\d{0,2}(\.\d\d?)?$
Assuming 0.01 - 99.99, it's a bit more complicated:
^0{0,2}(\.(0[1-9]|[1-9]\d?))?|\d{0,2}(\.\d\d)?$
And don't get me started on 0.02 - 99.98... :-)
So basically, don't do this. Convert the string to a numerical value and then do a regular interval check.
try
^\d{1,2}(\.\d{1,2})?$
it checks whether there are 1 or 2 digits and optionally if there is a dot it checks if there are 1 or 2 digits after the dot.
as answer to the comments of your question: nothing speaks against checking for the format before sending the request to a server or something else. range checks could be done somewhere else.
It's not the best but works
(0\.01|0\.02|0\.03| ... |99\.98|99\.99)
Since you're in Rails, you might be better served using validates_numericality_of in your model:
validates_numericality_of :cost, :greater_than_or_equal_to => 0.01,
:less_than_or_equal_to => 0.99
To prevent fractional pennies, use this in conjunction with validates_format_of:
validates_format_of :cost, :with => /\A\d*(\.\d{1,2})?\Z/
This leverages the strength of each validation.

Resources