I want a regex code that accepts only a list of characters that are seperated by a comma or a space - regex

So my problem is that i have a text field and i want the user to type a list of days only and to not accept any other word for example :
monday tuesday saturday
or monday,tuesday,saturday
this is what i wrote
"\b(monday|tuesday|wednesday|thursday|friday|saturday|sunday|\b"
but this didn't work i don't know why i'm a regex beginner and i need some help, thank you guys.

^((monday|tuesday|wednesday|thursday|friday|saturday|sunday)[, ])*(monday|tuesday|wednesday|thursday|friday|saturday|sunday)$
The ^ will anchor the pattern to match the start of the value, and the $ anchors at the end of the value. The combination of those two means the pattern will only match if the entire value matches. Without the anchors, the pattern would match anything which contains the pattern.
The pattern is saying that it must be zero or more dayname-followed-by-space-or-comma, followed by a dayname.

In your pattern the last pipe | of the alternation should be a closing parenthesis to close the group and you are not taking a comma or a space into account.
\b(monday|tuesday|wednesday|thursday|friday|saturday|sunday|\b
^
If you are not referring to the capturing groups in your code or tool, you could make them non capturing using (?: instead of (
You might update your pattern to use anchors ^ and $ to assert the start and the end of the string. Then match 1 day and repeat 0+ times matching another day prededing with a comma or a space.
^(?:mon|tues|wednes|thurs|fri|satur|sun)day(?:[, ](?:mon|tues|wednes|thurs|fri|satur|sun)day)*$
Regex demo
If you want to allow only the specified formats and for example not monday tuesday,saturday using a space AND a comma you could capture the space or comma the first time and then make use of a backreference using \1:
^(?:mon|tues|wednes|thurs|fri|satur|sun)day(?:([, ])(?:mon|tues|wednes|thurs|fri|satur|sun)day)?(?:\1(?:mon|tues|wednes|thurs|fri|satur|sun)day)*$
Regex demo

Related

How to exclude a specific string with REGEX? (Perl)

For example, I have these strings
APPLEJUCE1A
APPLETREE2B
APPLECAKE3C
APPLETEA1B
APPLEWINE3B
APPLEWINE1C
I want all of these strings except those that have TEA or WINE1C in them.
APPLEJUCE1A
APPLETREE2B
APPLECAKE3C
APPLEWINE3B
I've already tried the following, but it didn't work:
^APPLE(?!.*(?:TEA|WINE1C)).*$
Any help is appreciated as I'm also kinda new to this.
If you indeed have mutliple strings as you claim, there's no need to jam all that in one regex pattern.
/^APPLE/ && !/TEA|WINE1C/
If you have a single string, the best approach is probably to splice it into lines (split /\n/), but you could also use a single regex match too
/^APPLE(?!.*TEA|WINE1C).*/mg
You can use
^APPLE(?!.*TEA)(?!.*WINE1C).*
See the regex demo.
Details:
^ - start of string
APPLE - a fixed string
(?!.*TEA) - no TEA allowed anywhere to the right of the current location
(?!.*WINE1C) - no WINE1C allowed anywhere to the right of the current location
.* - any zero or more chars other than line break chars as many as possible.
If you don't want to match a string that has both or them (which is not in the current example data):
^APPLE(?!.*(WINE1C|TEA).*(?!\1)(?:TEA|WINE1C)).*
Explanation
^ Start of string
APPLE match literally
(?! Negative lookahead
.*(WINE1C|TEA) Capture either one of the values in group 1
.* Match 0+ characters
(?!\1)(?:TEA|WINE1C) Match either one of the values as long as it is not the same as previously matched in group 1
) Close the lookahead
.* Match the rest of the line
Regex demo

Regex: Matching anything after a certain group and up to empty line

This has been bugging me.
I want to capture from, e.g.:
Skills:
Java
Motorboating
Kite-crafting
C++
Sleeping
Training:
Uni of Pluto
College of Saturn
School of Venus
but only what comes after "Skills:" up to the first empty line before "Training:"
So far I've managed to use
(?<=Skills\:)[\n\r](.*)[\n\r]
But the definition of an empty line at the end of the regex has been making me mad. Some help, please?
You could match all lines that are not empty after Skills. If there can also be spaces at the start of the string before matching the first character:
(?<=Skills:)(?:\r?\n[^\S\r\n]*\S.*)+
The pattern matches:
(?<=Skills:) Assert Skills: directly to the left
(?: non capture group
\r?\n[^\S\r\n]*\S.* Match a newline, optional spaces without a newline. Then match a non whitespace char and the rest of the line.
)+ Repeat 1+ times to prevent an empty match
Regex demo
Or with a match instead of a lookbehind and a capture group:
\bSkills:((?:\r?\n[^\S\r\n]*\S.*)+)
Regex demo
This one should work for you
Demo
(?<=Skills\:\n)([^\n]+\n)*
Basically match at least one non-newline character on each line.

Match a part of a string using regex

I have a string and would like to match a part of it.
The string is Accept: multipart/mixedPrivacy: nonePAI: <sip:4168755400#1.1.1.238>From: <sip:4168755400#1.1.1.238>;tag=5430960946837208_c1b08.2.3.1602135087396.0_1237422_3895152To: <sip:4168755400#1.1.1.238>
I want to match PAI: <sip:4168755400#
the whitespace can be a word so i would like to use .* but if i used that it matches most of the string
The example on that link is showing what i'm matching if i use the whitespace instead of .*
(PAI: <sip:)((?:\([2-9]\d{2}\)\ ?|[2-9]\d{2}(?:\-?|\ ?))[2-9]\d{2}[- ]?\d{4})#
The example on that link is showing what i'm trying to achieve with .* but it should only match PAI: <sip:4168755400#
(PAI:.*<sip:)((?:\([2-9]\d{2}\)\ ?|[2-9]\d{2}(?:\-?|\ ?))[2-9]\d{2}[- ]?\d{4})#
I tried lookaround but failing.
Any idea?
thanks
Matching the single space can be updated by using a character class matching either a space or a word character and repeat that 1 or more times to match at least a single occurrence.
Note that you don't have to escape the spaces, and in both occasions you can use an optional character class matching either a space or hyphen [ -]?
If you want the match only, you can omit the 2 capturing groups if you want to.
(PAI:[ \w]+<sip:)((?:\([2-9]\d{2}\) ?|[2-9]\d{2}[ -]?)[2-9]\d{2}[- ]?\d{4})#
Regex demo
The regex should be like
PAI:.*?(<sip:.*?#)
Explanation:
PAI:.*? find the word PAI: and after the word it can be anything (.*) but ? is used to indicate that it should match as few as possible before it found the next expression.
(<sip:.*?#) capturing group that we want the result.
<sip:.*?# find <sip: and after the word it can be anything .*? before it found #.
Example

Match first of two conditions

My problem is simple, but I've been pulling my hair out trying to solve it. I have two types of strings: one has a semicolon and the other doesn't. Both have colons.
Reason: A chosen reason
Delete: Other: testing
Reason for action: Other; testing
Blah: Other; testing;testing
If the string has a semicolon, I want to match anything after the first one. If it has no semicolon, I want to match everything after the first colon. For lines above I should get:
A chosen reason
Other: testing
testing
testing;testing
I can get the semicolon to match by using ;(.*) and I can get the colon to match by using :(.*).
I tried using an alternative like this: ;(.*)|:(.*) thinking that maybe if I have the right order I can get it to match the semicolon first, and then the colon if there is no semicolon, but it always just matched the colon.
What am I doing wrong?
Edit
I added another test case above to match the requirements I had stated. For strings with no semicolon, it should match the first colon.
Also, "Reason" could be anything, so I am clarifying that as well in the test cases.
Second Edit
To clarify, I'm using the POSIX Regular Expressions (using in PostgeSQL).
My guess is that you might want to design an expression, maybe similar to:
:\s*(?:[^;\r\n]*;)?\s*(.*)$
Demo
Here you have a fast regex (233 steps) with no look aheads.
.*?:\s*(?:([^\n;]+)|.*?;\s*(.*))$
Check out the regex https://regex101.com/r/9gbpjW/3
UPDATED: to match any placeholder. Instead of just Reason
One option is to use an alternation to first check if the string has no ; If there is none, then match until the first : and capture the rest in group 1.
In the case that there a ; match until the first semicolon and capture the rest in group 1.
For the logic stated in the question:
If the string has a semicolon, I want to match anything after the first one.
If it has no semicolon, I want to match everything after the first colon
You could use:
^(?:(?!.*;)[^\r\n:]*:|[^;\r\n]*;)[ \t]*(.*)$
Explanation
^ Start of string
(?: Non capturing group
(?!.*;) Negative lookahead (supported by Postgresql), assert string does not contain ;
[^\r\n:]*: If that is the case, match 0+ times not : or a newline, then match :
| Or
[^;\r\n]*; Match 0+ times not ; or newline, then match ;
) Close non capturing group
[ \t]* Match 0+ spaces or tabs
(.*) Capturing group 1, match any char 0+ times
$ End of string
Regex demo | Postgresql demo
regex = .*?:(?(?!.*;)(.*)|.*?;(.*))
demo

Regex: pattern repeated capture – delimit the matching at the end of the pattern - non capture group and lookaheads negative example

I wish to match the end of my text and for it I have to match all the characters and the line breaks.
But I must exclude the beginning of the next capture!
What I want is to delimit the end of the pattern where the next pattern begins.
I tried to replace
[^-]
by something like
(?!-{2}\\*{3})
It doesn't work !
So I want to capture the number and I want to capture the whole paragraph (some text) between (--*** x ***)
Using this regex seems to work:
--\*{3}([\d]*)\*{3}(((?!-).*\n)*)
1st Capturing group: The digit inside the stars.
2nd Capturing group: The text between the "headers"
3rd Capturing group: The last line of the paragraph.
A link with the regex tested:
https://regex101.com/r/xJ0gC6/1
I found exactly what I wanted! :)
--\*{3}([^!*]*)\*{3}((?:(?!-{2}\*{3})(?:\n|.))*)
I must group what I want and what I don't want.
For that I must use a 'non-capture group' and a 'negative lookahead':
(?!nowant)(?:want)
Then I must use a 'non-capture group' to agregate the matching:
(?:(?!nowant)(?:want))
After, I add the quantifier '*'
(?:(?!nowant)(?:want))*
And finally, I add a 'capture group':
((?:(?!nowant)(?:want))*)
So here is the regex:
((?:(?!-{2}\*{3})(?:\n|.))*)
You can see the complete Regex here :
https://regex101.com/r/xJ0gC6/2