Javascript regex for consective character checker and one exception - javascript

Need to create a regex for a string with below criteria
Allowable characters:
uppercase A to Z A-Z
lowercase a to z a-z
hyphen `
apostrophe '
single quote '
space
full stop .
numerals 0 to 9 0-9
Validations:
Must start with an alphabetic character a-zA-Z
Cannot have consecutive non-alpha characters except for a full stop followed by a space .
The regex I created
^(?!.*[0-9'`\.\s-]{2})[a-zA-Z][a-zA-Z0-9-`'.\s]+$
Not sure how to put an exception to allow a full stop followed by a space. Please advise.

"Cannot have non-alphabetic characters at the start"
make sure that the string always starts with either a-z or A-Z
(/^[a-zA-Z]+/).test(str)
"Cannot have consecutive non-alpha characters except for a full stop followed by a space"
split at full-stop and space sequence ... /(\.[ ]+)/
"Cannot have consecutive non-alpha characters except for a full stop followed by a space"
for every entry make sure that ...
it either equals ... . ... "except for a full stop followed by a space"
or it matches ... /^((?<![-’'. 0-9])[-’'. 0-9]|[a-zA-Z]+)+$/ ... "Cannot have consecutive non-alpha characters" (But can feature alphabetic sequences.)
for the non consecutiveness make use of a negative lookbehind which ensures that specific non-alpha characters can not be preceded by their own kind.
function validateString(str) {
// [https://regex101.com/r/GlWgZ4/1]
const regXSequence = (/^((?<![-’'. 0-9])[-’'. 0-9]|[a-zA-Z]+)+$/);
str = String(str);
return (
// [https://regex101.com/r/GlWgZ4/2]
(/^[a-zA-Z]+/).test(str) &&
// split at full-stop and space sequence
str.split(/(\.[ ]+)/).every(
item => (item === '. ') || regXSequence.test(item)
)
);
}
console.log(
'- Must contain alphabetic characters,\n- Cannot have non-alphabetic characters at the start,\n- Cannot have consecutive non-alpha characters except for a full stop followed by a space ...',
validateString(
"AaaaaAA'a'. a0a1a1aa. a0a1a.aa. a0a1a-aa. 0abc0a-b’c'dfhf.ejg f0a9sdfgjgjgkj"
)
);
console.log(
'Cannot have non-alphabetic characters at the start ...',
validateString(
" AaaaaAA'a'. a0a1a1aa. a0a1a.aa. a0a1a-aa. 0abc0a-b’c'dfhf.ejg f0a9sdfgjgjgkj"
)
);
console.log(
'Cannot have consecutive non-alpha characters except for a full stop followed by a space ...',
validateString(
"AaaaaAA'a'. a0a1a1aa. a0a1a.aa. a0a1a-aa. 0abc0a-b’c'dfhf.ejg f0a9sdfgjgjgkj"
)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

You can use
/^(?!.*(?!\.\s)[\s`'.-]{2})[a-zA-Z][a-zA-Z0-9.\s`'-]*$/
See the regex demo and the regex graph:
.
Details:
^ - start of string
(?!.*(?!\.\s)[\s'.-]{2})`
[a-zA-Z] - an ASCII letter
[a-zA-Z0-9.\s'-]- zero or more (due to) ASCII letters or digits, .`, whitespace, backtick, singlq straight quotation mark or hyphen chars
$ - end of string.
See the JavaScript demo:
const texts = ['An abc with 123.', 'An abc with 123...', 'A 123 abc . '];
const re = /^(?!.*(?!\.\s)[\s`'.-]{2})[a-zA-Z][a-zA-Z0-9.\s`'-]*$/;
for (const text of texts) {
console.log(text, '=>', re.test(text));
}

Related

How to check is string has both letter and number in javascript

I have string "JHJK34GHJ456HJK". How to check if this string has both letter and number, doesn't have whitespace, doesn't have special characters like # - /, If has only letter or only number didn't match.
I try with regex below, result is true if string is only number or letter.
const queryLetterNumber = /^[A-Za-z0-9]*$/.test("JHJK34GHJ456HJK");
const input= [
'JHJK34GHJ456HJK',
'JHJKAAGHJAAAHJK',
'123456789012345',
'JHJK34 space JK',
'JHJK34$dollarJK'
];
const regex = /^(?=.*[0-9])(?=.*[A-Za-z])[A-Za-z0-9]+$/;
input.forEach(str => {
console.log(str + ' => ' + regex.test(str));
});
Output:
JHJK34GHJ456HJK => true
JHJKAAGHJAAAHJK => false
123456789012345 => false
JHJK34 space JK => false
JHJK34$dollarJK => false
Explanation:
^ - anchor at beginning
(?=.*[0-9]) - positive lookahead expecting at least one digit
(?=.*[A-Za-z]) - positive lookahead expecting at least one alpha char
[A-Za-z0-9]+ - expect 1+ alphanumeric chars
$ - anchor at end
you should use a regular expression to check for alphanumeric content in the string
/^[a-z0-9]+$/i
The above is a sample that checks for a-z and numbers from 0-9. however, review other options as given here

Is there a RegEx to extract semicolon separated values from a string... possibly containing string with semicolon

I would like to extract values from a string semicolon separated values that could also contains semicolon but not as separator. The RegEx I found on this website (I lost the post) is almost complete because it separates the key and it's value.
Example:
my.parameter 10; the.foo "Procedural Map"; pve; server.description "This; is \"my\", my description,.\n"
Current result with [^; "]+|"(?:\\"|[^"])*"/g
[
'server.seed',
'10',
'pve',
'server.level',
'"Procedural Map"',
'server.description',
'"This; is \\"my\\", server; description,."'
]
Desired result
[
'my.parameter 10',
'the.foo "Procedural Map"',
'pve',
'server.description "This; is \"my\", server; description,.\n"'
]
Can you help me to improve the RegEx to group the parameter and it's value?
You could use a repeating pattern to first match any char except the ; and then optionally match from an opening till closing double quote and match the escaped double quotes in between.
After that optionally repeat the character class [^";\\]* to also match what comes after the closing double quote.
[^;"\\]+(?:"(?:[^"\\]*(?:\\.[^"\\]*)*)"[^";\\]*)*
[^;"\\]+ Match 1+ times any char except ; " \
(?: Non capture group to repeat as a whole
" Match literally
(?: Non capture group
[^"\\]* Match 0+ times any char except " \
(?:\\.[^"\\]*)* Optionally repeat matching \ and any char followed by 0+ times any char except " and \
) Close the non capture group
" Match literally
[^";\\]* Optionally match any char except " ; \
)* Close the outer non capture group and optionally repeat
Regex demo
I found a workaround by replacing separator by the ASCII separator (␟) then splitting the result.
const separatorPattern = /; (?=([^"]*"[^"]*")*[^"]*$)/g;
const myRawString = "server.seed 10; server.pve, server.level \"Procedural Map\"; server.description \"This; is \\\"my\\\", server; description,.\"";
const replacedSeparator = myRawString.replace(separatorPattern, "␟");
const parameters = replacedSeparator.split("␟");
console.log(parameters);
/*[
'server.seed 10',
'server.pve, server.level "Procedural Map"',
'server.description "This; is \\"my\\", server; description,."'
]*/

How to match 2 separate numbers in Javascript

I have this regex that should match when there's two numbers in brackets
/(P|C\(\d+\,{0,1}\s*\d+\))/g
for example:
C(1, 2) or P(2 3) //expected to match
C(43) or C(43, ) // expect not to match
but it also matches the ones with only 1 number, how can i fix it?
You have a couple of issues. Firstly, your regex will match either P on its own or C followed by numbers in parentheses; you should replace P|C with [PC] (you could use (?:P|C) but [PC] is more performant, see this Q&A). Secondly, since your regex makes both the , and spaces optional, it can match 43 without an additional number (the 4 matches the first \d+ and the 3 the second \d+). You need to force the string to either include a , or at least one space between the numbers. You can do that with this regex:
[PC]\(\d+[ ,]\s*\d+\)
Demo on regex101
Try this regex
[PC]\(\d+(?:,| +) *\d+\)
Click for Demo
Explanation:
[PC]\( - matches either P( or C(
\d+ - matches 1+ digits
(?:,| +) - matches either a , or 1+ spaces
*\d+ - matches 0+ spaces followed by 1+ digits
\) - matches )
You can relax the separator between the numbers by allowing any combination of command and space by using \d[,\s]+\d. Test case:
const regex = /[PC]\(\d+[,\s]+\d+\)/g;
[
'C(1, 2) or P(2 3)',
'C(43) or C(43, )'
].forEach(str => {
let m = str.match(regex);
console.log(str + ' ==> ' + JSON.stringify(m));
});
Output:
C(1, 2) or P(2 3) ==> ["C(1, 2)","P(2 3)"]
C(43) or C(43, ) ==> null
Your regex should require the presence of at least one delimiting character between the numbers.
I suppose you want to get the numbers out of it separately, like in an array of numbers:
let tests = [
"C(1, 2)",
"P(2 3)",
"C(43)",
"C(43, )"
];
for (let test of tests) {
console.log(
test.match(/[PC]\((\d+)[,\s]+(\d+)\)/)?.slice(1)?.map(Number)
);
}

Regex uppercase separation but not separating more than 1 next to each other

I have array of values which I have to separate by their uppercase. But there are some cases where the value of the array has 2, 3 or 4 serial uppercases that I must not separate. Here are some values:
ERISACheckL
ERISA404cCheckL
F401kC
DisclosureG
SafeHarborE
To be clear result must be:
ERISA Check L
ERISA 404c Check L
F 401k C
Disclosure G
Safe Harbor E
I tried using:
value.match(/[A-Z].*[A-Z]/g).join(" ")
But of couse it is not working for serial letters.
One option could be matching 1 or more uppercase characters asserting what is directly to the right is not a lowercase character, or get the position where what is on the left is a char a-z or digit, and on the right is an uppercase char.
The use split and use a capture group for the pattern to keep it in the result.
([A-Z]+(?![a-z]))|(?<=[\da-z])(?=[A-Z])
( Capture group 1 (To be kept using split)
[A-Z]+(?![a-z]) Match 1+ uppercase chars asserting what is directly to the right is a-z
) Close group 1
| Or
(?<=[\da-z])(?=[A-Z]) Get the postion where what is directly to left is either a-z or a digit and what is directly to the right is A-Z
Regex demo
const pattern = /([A-Z]+(?![a-z]))|(?<=[\da-z])(?=[A-Z])/;
[
"ERISACheckL",
"ERISA404cCheckL",
"F401kC",
"DisclosureG",
"SafeHarborE"
].forEach(s => console.log(s.split(pattern).filter(Boolean).join(" ")))
Another option is to use an alternation | matching the different parts:
[A-Z]+(?![a-z])|[A-Z][a-z]*|\d+[a-z]+
[A-Z]+(?![a-z]) Match 1+ uppercase chars asserting what is directly to the right is a-z
| Or
[A-Z][a-z]* Match A-Z optionally followed by a-z to also match single uppercase chars
| Or
\d+[a-z]+ match 1+ digits and 1+ chars a-z
Regex demo
const pattern = /[A-Z]+(?![a-z])|[A-Z][a-z]*|\d+[a-z]+/g;
[
"ERISACheckL",
"ERISA404cCheckL",
"F401kC",
"DisclosureG",
"SafeHarborE"
].forEach(s => console.log(s.match(pattern).join(" ")))
function formatString(str) {
return str.replace(/([A-Z][a-z]+|\d+[a-z]+)/g, ' $1 ').replace(' ', ' ').trim();
}
// test
[
'ERISACheckL',
'ERISA404cCheckL',
'F401kC',
'DisclosureG',
'SafeHarborE'
].forEach(item => {
console.log(formatString(item));
});

How can I utilize RegExp to check for string?

Create a function that given a string, retains only the letters A-Z (upper and lowercase), 0-9 digits, and whitespace characters. Also, returns "Not a string!" if the entry type is not a string.
So far, I have:
function notAString(string) {
var regex = new RegExp(`^(?=.*[A-Za-z])\d\s`, 'g');
if (regex.test(string)) {
return "String!";
} else {
return "Not a string!";
}
}
I am only getting "Not a string!" returned, even if it is a string.
I'm not sure many people would agree with your definition of string! But based on the sequence you described, that would be ^[A-Za-z0-9\s]+$
Check it out at https://regex101.com/
Your RegEx should be ^[A-Za-z 0-9]*$:
Where
^ asserts position at start of a line
A-Z matches a single character in the range between A (index 65) and Z (index 90) (case sensitive)
a-z matches a single character in the range between a (index 97) and z (index 122) literally (case sensitive)
matches the space character
0-9 matches a single character in the range between 0 (index 48) and 9 (index 57) literally (case sensitive)
* quantifier — matches between zero and unlimited times, as many times as possible, giving back as needed
$ asserts position at the end of a line
You can also use Conditional (ternary) operator to simplify the solution like the following way:
function notAString(string) {
var regex = new RegExp(`^[A-Za-z 0-9]*$`, 'g');
return regex.test(string)? 'String!' : 'Not a string!';
}
console.log(notAString('123 Test string')); // String!
console.log(notAString('Test#string')); // Not a string!

Categories

Resources