Regex for given pattern - javascript

I have below test case
hello how are you // 1. Allow
hello how are you // 2. Not Allow
hello < // 3. Not Allow
for the following Rules:
Allow spaces at start and end
Not allow more than one space between words
Not allow angle brackets < >
I am trying the below:
^([^<> ]+ )+[^<> ]+$|^[^<> ]+$
This is working, but when giving spaces at start or end it is not allowing.

I assume that you use your regex to find matches in the whole
text string (all 3 lines together).
I see also that both your alternatives contain starting ^ and ending $,
so you want to limit the match to a single line
and probably use m regex option.
Note that [^...]+ expression matches a sequence of characters other than
placed between brackets, but it does not exclude \n chars,
what is probably not what you want.
So, maybe you should add \n in each [^...]+ expression.
The regex extended such a way is:
^([^<> \n]+ )+[^<> \n]+$|^[^<> \n]+$
and it matches line 1 and 2.
But note that the first alternative alone (^([^<> \n]+ )+[^<> \n]+$)
also does the job.
It you realy want that line 2 should not match, please specify why.
Edit
To allow any number of spaces at the begin / end of each line,
add * after initial ^ and before final $, so that the
regex (first alternative only) becomes:
^ *([^<> \n]+ )+[^<> \n]+ *$
But it still matches line 2.
Or maybe dots in your test string are actually spaces, but you wrote
the string using dots, to show the numer of spaces?
You should have mentioned it in your question.
Edit 2
Yet another possibility, allowing dots in place of spaces:
^[ .]*((?:[^<> .\n]+[ .])+[^<> .\n]+|[^<> .\n]+)[ .]*$
Details:
^[ .]* - Start of a line + a sequence of spaces or dots, may be empty.
( - Start of the capturing group - container for both alternatives of
stripped content.
(?:[^<> .\n]+[ .])+ - Alternative 1: A sequence of "allowed" chars ("word") +
a single space or dot (before the next "word", repeated a few times.
This group does not need to be a capturing one, so I put ?:.
[^<> .\n]+ - A sequence of "allowed" chars - the last "word".
| - Or.
[^<> .\n]+ - Alternative 2: A single "word".
) - End of the capturing group.
[ .]*$ - The final (possibly empty) sequence of spaces / dots + the
end of line.
Of course, with m option.

Related

I want a regex that will select all characters including special characters, except the Last 4 Characters. Vanilla JS

let str = "AAAAA-0000021111-1111";
let res = str.match(/\d(?=\d{4})/g);
document.write(res);
//This didnt work, the output is given below:
Output:
0,0,0,0,0,2
// its only selecting these characters which are highlighted in bold AAAAA-0000021111-1111
And this is what I am expecting:
A,A,A,A,A,-,0,0,0,0,0,2,1,1,1,1,-
Basically, I want all characters to be selected including - or any other special characters except the last 4.
I am listing a couple of extra samples for a better understanding
Sample1: ABC-101010-1111
Expected output is: A,B,C,-,1,0,1,0,1,0,-
Sample2: ABCD101010-11111
Expected output is: A,B,C,D,1,0,1,0,1,0,-,1
I am using Vanilla JS.
Really appreciate your involvement in this.
Thanks in Advance Sir/Ma'am!!!
You can use
/(?!\d{1,4}$)./g
See the regex demo.
NOTE: If you need to match all chars except last four any chars, you will need to replace \d with . in the lookahead, and it can be even written in a bit more succint way:
/.(?!.{0,3}$)/g
See this regex demo.
Details:
. - any single char other than line break char
(?!.{0,3}$) - a negative lookahead that matches a location not immediately followed with zero to three chars other than line break chars, till end of string.
The regex will match any char other than a line break char (., to match line breaks, use [^], [\s\S]/[\d\D]/[\w\W] or add s flag) that does not start a sequence of one, two, three or four digits at the end of string ((?!\d{1,4}$)).
See a JavaScript demo:
console.log("AAAAA-0000021111-1111".match(/(?!\d{1,4}$)./g))
console.log("AAAAA-0000021111-1111".match(/.(?!.{0,3}$)/g))

Single regex to remove empty lines and double spaces from multiline input

I would like to combine two regex functions to clean up some textarea input. I wonder if it is even possible, or if I should keep it two separate ones (which work fine but aren't looking as pretty or clean).
I have adjusted either so that they utilize global and multiline (/gm) and are replaced by nothing (''). I tried with brackets and vertical/or lines in any position, but it never ends up giving the expected result, so I can only assume there is a way that I have overlooked or that I should keep it as is.
Regex 1: /^\s+[\r\n]/gm
Regex 2: /^\s+| +(?= )|\s+$/gm
Currently in JavaScript: string.replace(/^\s+[\r\n]/gm,'').replace(/^\s+| +(?= )|\s+$/gm,'')
The goal is to remove:
Empty spaces in the beginning and end of each line
Empty lines (including any in the very beginning and end)
Double spaces
Without it ending up on one and the same line. The single line breaks (\r\n) should still be there in the end.
Regex 1 is to remove any empty line (^\s+[\r\n]), Regex 2 does the trimming of whitespaces in the beginning (^\s+) and end (\s+$), and removes double (and triple, quadriple, etc) spaces in between (+(?= )).
Input:
Let's
make this
look
a little
nicer
and
more
readible
Output:
Let's
make this
look
a little
nicer
and
more
readible
Edit: Many thanks to Wiktor Stribiżew and his comment for this complete solution:
/^\s*$[\r\n]*|^[^\S\r\n]+|[^\S\r\n]+$|([^\S\r\n]){2,}|\s+$(?![^])/gm
I'd suggest the following expression with a substitution template "$1$2" (demo):
/^\s*|\s*$|\s*(\r?\n)\s*|(\s)\s+/g
Explanation:
^\s* - matches whitespace from the text beginning
\s*$ - matches whitespace from the text ending
\s*(\r?\n)\s* - matches whitespace between two words located in different lines, captures one CRLF to group $1
(\s)\s+ - captures the first whitespace char in a sequence of 2+ whitespace chars to group $2

RegEx match end character only when other character is not present

I'm having quite some trouble to define a regEx that I'm needing....
Basically the idea is to detect all lines that end with a , or a ; character. For this I have defined the following regex:
(,|;)$
Which works fine for this, but then I have the exception that if there's a * character within that line (not necessarily starting with, but at some position), then I don't want to detect that match. Based on this sample:
/**
* Here there's a comment I don't want to find,
* but after this comment I do
*/
detectMe;
other,
I would intend to find 2 groups, the first one
/**
* Here there's a comment I don't want to find,
* but after this comment I do
*/
detectMe;
And the second one
other,
I've tried many things such as non capturing groups, negative looks ahead and also start of a string with [^\s*\*] with no success. Is there a way to do this?
Some of the regEx I've tried...
^[^\*](.*?)(,|;)$
^[^\s*\*](.*?)(,|;)$
To match an optional C comment and the following line ending with ; or , you may use
/(?:\/\*+[^*]*\*+(?:[^\/*][^*]*\*+)*\/\r?\n)?.*[;,]$/gm
See this regex demo
Details
(?:\/\*+[^*]*\*+(?:[^\/*][^*]*\*+)*\/\r?\n)? - an optional (as there is a ? quantifier after the group) non-capturing group matching 1 or 0 occurrences of
\/\*+[^*]*\*+(?:[^\/*][^*]*\*+)*\/ - a C comment pattern
\r?\n - a CRLF or LF ending
.*[;,]$ - a whole line that ends with ; or , ($ is the end of a line anchor here due to m modifier).
You can use this regex:
/^[^*]*?[,;]$/gm
It will start by mathing any number of characters not being '*', then match ',' or ';' at the end of the line. It uses the global and multiline flags to match all lines.

Catching start number and final number

i'm trying to create a regex to catch the first number in the line and the last one, but i'm having some problem with the last one:
The lines look like this:
00005 SALARIO MENSAL 17030 36.397.291,92 36.397.291,92
00010 HORAS TRABALHADAS 0798 19.731,93 19.731,93
And this is my regex:
(^\d+).*(\d)
As you can see here: http://regexr.com/3crbt is not working as expected. I can get the first one, but the last is just the last number.
Thanks!
You can use
/^(\d+).*?(\d+(?:[,.]\d+)*)$/gm
See the regex demo
The regex matches:
^ - start of the line
(\d+) - captures into Group 1 one or more digits
.*? - matches any characters but a newline, as few as possible up to
(\d+(?:[,.]\d+)*) - one or more digits followed with zero or more sequences of , or . followed with one or more digits (Group 2)
$ - end of the string
The /g modifier ensures we get all matches and /m modifier makes the ^ and $ match start and end of a line respectively.
I tried the following one:
(^(\d+))|(\d+$)
And its seems to work on the regexr.com thingy. But matching them up might require some assumptions that each line has at least two numbers.
You need to make the .* non-greedy by changing it to .*? and add + to the second digit sequence match.
^(\d+).*?(\d+)$
If you want to match the full last number, use this:
^(\d+).*?([\d\.,]+)$
Example

password validation using javascript

I need to match a password field using javascript with the following requirements:
Should be alpha numaric with at least one special character.
no spaces to be allowed
should be minimum 10 char and max 20 chars.
No repeate of char more than 2 times.
~,'.:;^| are not allowed
I have a regex
var password = /^(?=.[0-9])(?=.[!##$%^&])[a-zA-Z0-9!##$%^&]{10,20}$/;
how can i solve this?
This might be the required regex
^(?=.*[!##$%^&])(?!.*(.).*\1.*\1)[A-Za-z\d!##$%^&|]{10,20}$
(?=.*[!##$%^&]) ensures at least one occurrence of the listed characters.
(?!.*(.).*\1.*\1) ensures no character is repeated more than twice.
[A-Za-z\d!##$%^&|]{10,20} matches 10-20 occurrence of characters from the character class.
I would write separate rules (probably using regex for all of them - for consistency - unless performance is a great concern) that each relate directly to a rule on your list.
The code
var pw = "asddfak#kjg";
/* Should be alpha numaric with at least one special character. */
console.log(null !== pw.match(/[#+#$]/));
/* no spaces to be allowed */
console.log(null !== pw.match(/^\S+$/));
/* should be minimum 10 char and max 20 chars. */
console.log(null !== pw.match(/^.{10,20}$/));
/* No repeate of char more than 2 times. */
console.log(null === pw.match(/(.)(.*\1){2}/));
/* ~,'.:;^| are not allowed */
console.log(null !== pw.match(/^[^~,'.:;^|]+$/));
Although it is possible to make the regex more concise, I think it is much more maintainable to make the rules more literal to your intent. If performance is a significant issue (usually not for this kind of thing) then I would avoid regex, and implement the rules using string methods.
Regex Explained
/ // start regex pattern
[ // open character class
#+#$ // match one of these `special` characters
] // close character class
/ // end regex pattern
/ // start regex pattern
^ // start matched string
\S+ // one or more (`+`) not spaces (`\S`)
$ // end matched string
/ // end regex pattern
/ // start regex pattern
^ // start matched string
.{10,20} // between 10 and 20 of any character (`.`)
$ // end matched string
/ // end regex pattern
/ // start regex pattern
(.) // any character captured as group 1
(.*\1){2} // followed by zero or more of anything (`\.*`) and then the captured group 1 (`\1`) two times (`{2}`)
/ // end regex pattern
/ // start regex pattern
^ // start matched string
[ // open character class
^~,'.:;^| // not (`^`) one of these characters
]+ // close character class
$ // end matched string
/ // end regex pattern
p.s. you should keep a lot of comments with regex you use, because unlike books, they are much easier written than read
This should work:
/^(?=.*?[!##$%^&])(?:([a-zA-Z0-9!##$%^&])(?!.*?\1.*?\1)){10,20}$/
(if by repeat more than 2 times you mean the same character can't appear thrice)
Explanation:
1st condition: at the very beginning, we'll go through the whole string a first time until we find a special character, as soon as we have it, we stop, if we don't, it fails (Source): (?=.*?[!##$%^&])
2nd condition: nothing to do, [a-zA-Z0-9!##$%^&] doesn't allow spaces anyway
3rd condition: quantifier: {10,20}
4th condition: the subtle one: as we get through the string, for each character captured, we check the it's not repeated twice more (same source): (?!.*?\1.*?\1)
5th condition: same as whitespaces
based on your 5 things in your requirements this is exact pattern you need
^(?=.*[!##$%^&])(?!.*(.).*\1.*\1)[^\s~,'.:;^|]{10,20}$

Categories

Resources