Regex to disallow certain characters in specific sequence - javascript

I have a regular expression that allows only letters, numbers, spaces or hyphens. However, I'd like to disallow the user to do the following:
hello--world Have more than one hyphen sitting next to each other
--hello Have a hyphen in the beginning. It must have a number or letter first
How do I accomplish this? My current regex looks like this:
let alphanumericTest = new RegExp("^\s*([0-9a-zA-Z- ]*)\s*$");

You can try this regex expression. ^\s*[0-9a-zA-Z](?:(?!--)[0-9a-zA-Z- ])*$
This is a demo.

You could make you match a bit more efficient without using a negative lookahead for matching non consecutive hyphens using repeating groups which can optionally start with an hyphen after the first word.
^[ ]*[0-9a-zA-Z]+(?:-[0-9a-zA-Z]+)*-?(?:[ ]+-?(?:[0-9a-zA-Z]+-?)*)*$
(Used [ ] to match a space for clarity)
Explanation
^ Start of string
[ ]* Match 0+ spaces
[0-9a-zA-Z]+ Match 1+ times any of the listed
(?:-[0-9a-zA-Z]+)* Repeat 0+ times matching a hyphen and 1+ what is listed
-? Match optional hyphen
(?: Non capturing group
[ ]+-?(?:[0-9a-zA-Z]+-?)* Match 1+ spaces, optional hyphen, repeat 0+ times what is listed and optional hyphen
)* Close outer non capturing group and repeat 0+ times
$ End of string
Regex demo

Try:
let alphanumericTest = new RegExp("^(?!-)(?!.*--)[0-9a-zA-Z- ]+(?<!-)$");
This checks that the first character is not a - and that there are no consecutive --s anywhere in the string

Related

How Can I Validate a URL end point in Javascript?

I want to validate the url end point using regex. Example end point like: /user/update.
First I tried with (/[A-Za-z0-9_.:-~/]*) but also matches http://url.com/user/update with javascript regex. I want the string to only validate pass if it is equal to /user/update like end points
You can use regex look behind technique to get the path after the .com with /(?<=.com).*/
const matchEndPoint = (str) => str.match(/(?<=.com).*/)
const [result] = matchEndPoint('http://url.com/user/update');
console.log(result)
You might use a pattern like
^\/[\w.:~-]+\/[\w.:~-]+$
Regex demo
Or for example not allowing consecutive dashes like -- and match one or more forward slashes:
^\/\w+(?:[.:~-]\w+)*(?:\/\w+(?:[.:~-]\w+)*)*$
Explanation
^ Start of string
\/\w+ Match / and 1+ word chars
(?:[.:~-]\w+)* Optionally repeat a char of the character class and 1+ word chars
(?: Non capture group
\/\w+ Match / and 1+ word chars
(?:[.:~-]\w+)* Optionally repeat a char of the character class and 1+ word chars
)* Close group and optionally repeat
$ End of string
Regex demo

How to combine a few regex expressions in JavaScript?

I have a few requirements to validate email address and have a few regex expressions for that purpose.
But how I can combine them to one regex to make it work correctly?
(?=^\\S+#\\S+\\.\\S+$)
Dotted email address
(?=^[A-Za-z0-9#$\\._-]+$)
allows alphanumeric, '#', '.', '_', '-'
(?=^[A-Za-z0-9].*$)
cannot start with special character
(?=^.{5,100}$)
between 5 and 100 characters
(?=^((?!([0-9]{9,}\\1)).)*$)
Not nine or more numbers
(^(?!.*[#].*[#]).*$)
One at mark
Try concatenating your expressions:
const emailRegex = /(?=^\S+#\S+\.\S+$)(?=^[A-Za-z0-9#$\._-]+$)(?=^[A-Za-z0-9].*$)(?=^.{5,100}$)(?=^((?!([0-9]{9,}\1)).)*$)(^(?!.[#].[#]).*$)/;
There are a lot of custom rules using lookaheads, from which you can omit a few by matching instead of asserting.
^(?=\S{5,100}$)(?!\S*\d{9})[A-Za-z0-9][A-Za-z0-9$\\._-]*#[A-Za-z0-9$\\._-]+\.[A-Za-z0-9]+$
^ Start of string
(?=\S{5,100}$) Assert 5-100 non whitspace chars
(?!\S*\d{9}) Assert not 9 consecutive digits in the string
[A-Za-z0-9] Match a single char A-Z a-z or a digit
[A-Za-z0-9$\\._-]* Optionally repeat what is listed in the character class
# Match an # char (Note that you can omit the square brackets [#])
[A-Za-z0-9$\\._-]+ Match 1+ times any of the listed in the character class
\.[A-Za-z0-9]+ Match a . and 1+ times any of the listed in the character class
$ End of string
Regex demo

regex to match question sentences in long text

I have a long text in form of a string.
This text includes a lot of questions that are at the same time the headers of sections.
These headers always start with a number+dot+whitespace character combination and end with a question mark, I am trying to extract these strings.
This is what I've got so far: longString.match(/\d\.\s+[a-zA-Z]+\s\\?/g).
Sure enough this doesn't work.
In your example you use [a-zA-Z]+, but you might extend that to matching 1 or more word characters using \w+
This part at the end of the pattern \s\\? matches an expected whitespace char followed by an optional backslash.
To match multiple words, you can optionally repeat the pattern to match a word preceded by 1 or more whitespace characters.
You one option is to use
\d\.\s+\w+(?:\s+\w+)*\s*\?
Explanation
\d\. Match a single digit (for 1 or digits use \d+)
\s+\w+ Match a . and 1+ whitspace chars and 1+ word chars
(?:\s+\w+)* Optionally repeat 1+ whitspace chars and 1+ word chars
\s*\? Match 0+ whitespace chars and a question mark.
Regex demo
A broader match might be matching at least a single time any char except a question mark or whitespace char after the digit, dot and whitespace:
\d\.\s+[^\s?]+(?:\s+[^\s?]+)*\?
Regex demo

Updating my regex to include dots and hyphens

My regex code [A-Z]{1,}\d{3,}\w? works fine returning strings like CX3623, M3326, Y2362 but I also want to be able to return strings which are in the following format:
YH321-2
V2021/V2022
1.2A-2351
YGH256-4268
What should I add to the regex?
Demo: https://regex101.com/r/MjPkFh/2
For the first part, you could match the different formats using an alternation.
You could make the second part optional using an optional non capturing group (?:...)? and match either / or - optionally followed by chars A-Z and 1+ digits.
\b(?:[A-Z]+ )?(?:[A-Z]*\d{3,}|\d+(?:\.\d+)?[A-Z]+)(?:[\/-][A-Z]*\d+)?\b
Explanation
\b Word boundary
(?:[A-Z]+ )? Optionally match 1+ chars A-Z followed by a space
(?: Non capture group
[A-Z]*\d{3,} Match 0+ times A-Z and 3 or more digits
| Or
\d+(?:\.\d+)?[A-Z]+ Match 1+ digits with an optional decimal part and 1+ times A-Z
) Close group
(?: Non capture group
[\/-][A-Z]*\d+ Match either / or -, 0+ times A-Z and 1+ digits
)? Close group and make optional
\b Word boundary
Regex demo

How to match any string that contains no consecutively repeating letter

My regular expression should match if there aren't any consecutive letters that are the same.
for example :
"ploplir" should match
"ploppir" should not match
so I use this regular expression:
/([.])\1{1,}/
But It does the exact contrary of what I want. How can I make the match work correctly?
Code
See regex in use here
\b(?!\w*(\w)\1)\w+\b
var r = /\b(?!\w*(\w)\1)\w+\b/g
var s = "ploplir ploppir"
console.log(s.match(r))
Explanation
\b Assert position as a word boundary
(?!\w*(\w)\1\w*) Negative lookahead ensuring what follows doesn't match
\w* Match any number of word characters
(\w) Capture a word character into capture group 1
\1 Match the same text as most recently matched by the 1st capture group
\w+ Match one or more word characters
\b Assert position as a word boundary
Maybe you could use lookarounds to check if there are no consecutive letters in the string:
^(?!.*(.)(?=\1)).*$
Explanation
From the beginning of the string ^
A negative look ahead (?!
Which asserts that following .* a character (.) is not followed by the same character (?=\1) using the group reference \1
Close the negative lookahead
Match zero or more characters .*
The end of the string

Categories

Resources