regex for certain characters and rules [closed] - regex

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am trying to build a regex to ensure a given string only contains these 13 certain characters/rules. I am having a bit of trouble. Any help would be appreciated.
Allowed Characters:
a-z
A-Z
0-9
! (Exclamation point)
- (Hyphen)
_ (Underscore)
. (Period)
* (Asterisk)
' (Single Quote)
( (Open parenthesis)
) (Close parenthesis)
(No consecutive spaces)
*. (CANNOT end with a period)
So Far I have this
/^[+\-0-9().!-_*' ]+$/g
But not getting expected results. Thank you in advance.
EDIT:
Sorry first time posting here. Here are some test cases(JS). Second one should not pass because it has consecutive spaces and ends with period.:
let testOne = "Testing Regex - 2021 Th*i)s_On(e_pa!'ss.es.end";
let testTwo ="Testing Regex - 2021 Th*i)s_On(e_pa!'ss.es.end but
shouldn't.";
testOne.match(/^[+\-\w().!-_*' ]+$/g);
testTwo.match(/^[+\-\w().!-_*' ]+$/g);

Some issues:
Your regex does not allow for Latin letters: you didn't list them.
Your regex allows for some additional characters (including $, # and %) because of !-*, which specifies a range.
There is no provision for not allowing more than a single space.
There is no provision for not allowing a dot as last character
The g modifier has little purpose when you have end-of-string markers requiring that a match will always match the whole input.
From your regular expression it seems you also require that the input has at least 1 character.
Taken all that together, we get this:
/^(?!.*? )(?!.*?\.$)[\w+\-().!*' ]+$/

You can try this:
^(?!.* )[\w!()\-*'\s.]+[\w!()\-*'\s]$
https://regex101.com/r/kTcJUN/3
And if you don't want to allow space character at the end of string then:
^(?!.* )[\w!()\-*'\s.]+[\w!()\-*']$
Explanation:
(?!.* ) - Exclude double space in string
\w - any word character. Matches any letter, digit or underscore. Equivalent to [a-zA-Z0-9_].
! - literally !
( - literally (
) - literally )
- - literally -
* - literally *
' - literally '
\s - space character
. - literally .
+ - quantifier. Matches between one and unlimited times.
[\w!()\-*'\s] - Allow a single character from the list. Putting this just before $ (end of line) makes this character last in string.

Related

Customised regex in ruby [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I want to check if a string states Above 60. Example:
'>60', '> 60', 'above60', 'above 60', 'Above60', 'Above 60', OR more than 1 space in between (> and 60), (above and 60), (Above and 60).
How can I write a regex to validate a string that starts with either (>, above or Above) then any number of spaces and ends with 60?
How can I write a regex to validate a string that starts with either (>, above or Above) then any number of spaces and ends with 60?
It's very straight forward:
a string that starts with either >, above or Above
/^(>|above|Above)/
then any number of spaces
/^(>|above|Above)\s*/
and ends with 60
/^(>|above|Above)\s*60$/
Note that in Ruby, ^ and $ match beginning and end of a line, not string. You might want to change that to \A and \z respectively. And instead of specifying both cases explicitly (above / Above), you could append an i to make the regexp case-insensitive, i.e. /^(>|above)\s*60$/i.
As always, there's more than one way to get the desired result. I can recommend Rubular for fiddling with regular expressions: https://rubular.com/r/EEHBSOB3PK2Djk
r = /\A(?:>|[aA]bove) *60\z/
['>60', '> 60', 'above60', 'above 60', 'Above60', 'Above 60'].all? do |s|
s.match?(r)
end
#=> true
[' >60', '> 600', ' above60', 'above 600', 'Above60 '].any? do |s|
s.match?(r)
end
#=> false
We can write the regular expression in free-spacing mode to make it self-documenting.
/
\A # match beginning of string
(?: # begin a non-capture group
> # match '>'
| # or
[aA] # match 'a' or 'A'
bove # match 'bove'
) # end non-capture group
[ ]* # match 0+ spaces
60 # match '60'
\z # match end of string
/x # invoke free-spacing regex definition mode
Notice that in the above I placed the space in a character class ([ ]). Alternatively I could have escaped the space, used [[:space:]] or one of a few other options. Without protecting the space in one of these ways it would be stripped out (when using free-spacing mode) before the regex is parsed.
When spaces are to be reflected in a regex I use space characters rather than whitespace characters (\s), mainly because the latter also match end-of-line terminators (\n and possibly \r) which can result in problems.
This should work :
/(>|above|more than){0,1} *60\+*/i
The i at the end of the regex is for case insensitivity.
If you need additional prefixes, just add it after more than separated by a pipe |

Filter lines based on range of value, using regex [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
What regex will work to match only certain rows which have a value range (e.g. 20-25 days) in the text raw data (sample below):
[product-1][arbitrary-text][expiry-17days]
[product-2][arbitrary-text][expiry-22days]
[product-3][arbitrary-text][expiry-29days]
[product-4][arbitrary-text][expiry-25days]
[product-5][arbitrary-text][expiry-10days]
[product-6][arbitrary-text][expiry-12days]
[product-7][arbitrary-text][expiry-20days]
[product-8][arbitrary-text][expiry-26days]
'product' and 'expiry' text is static (doesn't change), while their corresponding values change.
'arbitrary-text' is also different for each line/product. So in the sample above, the regex should only match/return lines which have the expiry between 20-25 days.
Expected regex matches:
[product-2][arbitrary-text][expiry-22days]
[product-4][arbitrary-text][expiry-25days]
[product-7][arbitrary-text][expiry-20days]
Thanks.
Please check the following regex:
/(.*-2[0-5]days\]$)/gm
( # start capturing group
.* # matches any character (except newline)
- # matches hyphen character literally
2 # matches digit 2 literally
[0-5] # matches any digit between 0 to 5
days # matches the character days literally
\] # matches the character ] literally
$ # assert position at end of a line
) # end of the capturing group
Do note the use of -2[0-5]days to make sure that it doesn't match:
[product-7][arbitrary-text][expiry-222days] # won't match this
tested this one and it works as expected:
/[2-2]+[0-5]/g
[2-2] will match a number between 2 and 2 .. to restrict going pass the 20es range.
[0-5] second number needs to be between 0 and 5 "the second digit"
{2} limit to 2 digits.
Edit : to match the entire line char for char , this shoudl do it for you.
\[\w*\-\d*\]\s*\[\w*\-[2-2]+[0-5]\w*\]
Edit2: updated to account for Arbitrary text ...
\[(\w*-\d*)\]+\s*\[(\w*\-\w*)\]\s*\[(\w*\-[2-2]+[0-5]\w*)\]
edit3: Updated to match any character for the arbitrary-text.
\[(\w*-\d*)\]\s*\[(.*)\]\s*\[(\w*\-[2-2][0-5]\w*)\]
.*\D2[0-5]d.*
.* matches everything.
\D prevents numbers like 123 and 222 from being valid matches.
2[0-5] covers the range.
d so it doesn't match the product number.
I pasted your sample text into http://regexr.com
It's a useful tool for building regular expressions.
You can try this one :
/(.*-2[0-5]days\]$)/gm
try it HERE

validating last two characters to follow a pattern [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a string abcdefgh,
i want to check if the last two characters are alpha numeric/alphabets but not numeric
i.e. it can end in a1, 1a, aa but not 11
are there any regex gurus who can chipin
The regex should return the below results for the strings
abcd - True
abc1d - True
abcd1 - True
abc12 - false
This should do it:
^.*(\d[a-zA-Z]|[a-zA-Z](\d|[a-zA-Z]))$
Online regex tool demo here.
Meaning:
^ the beginning of the string
.* any character except \n (0 or more times)
(
\d[a-zA-Z] a digit (0-9) followed by any character of a to z, A to Z
| OR
[a-zA-Z] any character of a to z, A to Z followed by
(\d|[a-zA-Z]) a digit or any character of a to z, A to Z
)
$ end of the string
Notice this matches the whole string, not only the two last chars, having those at the matched group one.
So, a letter and a digit, or a digit and a letter, or two letters?
([a-zA-Z]\d|\d[a-zA-Z]|[a-zA-Z][a-zA-Z])$
Depending on the regex system you're using, you can also use character classes such as :alpha:, but this one will work for all of them. Some regex syntaxes need a backslash in front of the parentheses and/or pipe symbol.
You can use
^.*[A-Za-z].|.[A-Za-z]$
Online test
You can use :
^.*([a-zA-Z]{2}|(\d[a-zA-Z])|([a-zA-Z]\d))$
DEMO
EXPLANATION:

matching a number pattern between special characters [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am trying to write a regular expression to extract only the number 120068018
!false!|!!|!!|!!|!!|!120068018!|!!|!false!
I am rather new to regular expressions and am finding this a daunting task.
I have tried using the pattern as the numbers always start with 1200
'/^1200+!\$/'
but that does not seem to work.
If your number always starts with 1200, you can do
/1200\d*/
This matches a string that starts with 1200 plus "however many digits follow". Depending on the 'dialect' of regex that you use, you might find
/1200[0-9]*/
more robust; or
/1200[[:digit:]]*/
which is more "readable"
Any of these can be "captured" with parentheses. Again, depending on the dialect, you may or may not need to escape these (add \ in front). Example
echo '||!!||!!||!!120012345||##!!##!!||' | sed 's/^.*\(1200[0-9]*\).*$/\1/'
produces
120012345
just as you wanted. Explanation:
sed stream editor command
s substitute
^.* everything from start of string until
\( start capture group
1200 the number 1200
[0-9]* followed by any number of digits
\) end capture
.*$ everything from here to end of line
/\1/ and replace with the contents of the first capture group
Use this:
/1200\d+/
\d is a meta-character that will match any digits.
Your regular expression didn't work because:
^ matches start of a string. You didn't have your number there.
$ matches end of the string. Again, your number is in the middle of the string.
applies to the immediately preceding character, meta-character or group. So 1200+ means 120 followed by 1 or more zeroes.
This is the regular expression you need:
/[0-9]+/
[0-9] Matches any number from 0 to 9
The + sign means 1 or more times.
If you want to get any number starting with 1200, then it would be
/1200[0-9]*/
Here I am using * because it allows zero or more. Otherwise, the number 1200 wouldn't be captured.
If you want to capture (extract) the String, surround it with parenthesis:
/(1200[0-9]*)/

What does this specific regex do? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
The regex is:
/^\/node?(?:\/(\d+)(?:\.\.(\d+))?)?/
I can understand that / in the beginning and the end are regex delimiters, also ^\/node is for a string starting with /node What's happening after that beats me!
You should look into getting a tool like RegexBuddy. It will explain everything in a given regex, as well as how it compiles and how it branches.
Assuming PCRE or similar:
/ //begin
^ //start of string
\/ //literal /
node? //I assume node is optional, normally it'd be (node)?
//? makes the previous expression optional
(
?: //non-capturing group (think of it like dont capture <this>)
\/ //literal /
(\d+) // one or more digits, 0-9
(
?: // another non-capturing group
\.\. // literal ..
(\d+) // one or more digits 0-9
)
? // optional once more
)
? // make the previous group optional
/ // end
? anything following this is "optional"
(?: non-capturing group
\/ escaped /
(\d+) -more than 1 digit - also in a capture group "()"
(?: again
\. - escaped .
\. - again
(\d+) - same as before
)?)? - not sure - what flavour of regex is this?
You are correct, the / at the start are pattern delimiters. Lets remove those for simplicity
^\/node?(?:\/(\d+)(?:\.\.(\d+))?)?
The (?:...) is a non-capturing group. This is a group that does not get grabbed into a match group. This is an optimisation, let's remove the ?: to make the pattern clearer.
^\/node?(\/(\d+)(\.\.(\d+))?)?
The \ is an escape character, so \/ is actually just a / but as these denote the start and end of the pattern then need to be escaped. The . matches (almost) any character so it needs to be escaped too.
The ? makes the receding pattern optional, so ()? means whatever is in the brackets appears zero or one times.
^ denotes the start of the string
\/node? matches /node or /nod
\/(\d+) matches / followed by one or more digits (the \d+). The digits are captured into the first match group
(\.\.(\d+))? matches .. followed by one or more digits (the \d+). The digits are captured into the second match group