Repeat a matching pattern that may not exist - javascript

We have this simple regular expression:
var regex = \a[bc]*\;
// matches 'ab', 'abb', 'accc'
but this regex also matches 'aa'.
In other words, because the pattern [bc] did not exist, it repeated the 'a'. But the intent was to catch the 'a' then any number of 'b' or 'c'.
How would you apply the * (repeat pattern) so it only acts on the previous character if it matched anything.

No. * is not applied to a in the regex. * is applied to only character class [bc].
You haven't matched the complete string. You have to use ^(starts with) and $(ends with) in your regex.
var regex = /^a[bc]*$/;
// ^ ^
OR use word boundary selector, if you want to match substring in a larger string.
var regex = /\ba[bc]*\b/;
// ^^ ^^
Demo:
var regex = /\ba[bc]*\b/;
document.write("regex.test('a'): " + regex.test('a')); // true
document.write("<br />regex.test('abc'): " + regex.test('abc')); // true
document.write("<br />regex.test('abcab'): " + regex.test('abcab')); // false
document.write("<br />regex.test('aa'): " + regex.test('aa')); // false
// Words in string
document.write("<br /><br />regex.test('this is a adbc'): " + regex.test('this is a adbc')); // true 'a'
document.write("<br />regex.test('this is adbc'): " + regex.test('this is adbc')); // false
Visual Representation

Related

How to verify that a certain character is inside two dedicated characters in javascript?

Let's say that the character we need to target is $, and we need to verify if it lies between two ' & '. The code will look something like this :
var str = " Verify '$' "
var str2 = " Let's see if ' The $ is inside ! ' "
var str3 = " I got $ "
console.log(verify(str)) //=> true
console.log(verify(str2)) //=> true
console.log(verify(str3)) //=> false
Javascript String.prototype.includes(), can be used to verify if $ exists in the string but I am not understanding how to verify if it is inside ' & ' ?
You could look for $, wrapped by '.
const check = string => /'.*\$.*'/.test(string);
console.log([
" Verify '$' ",
" Let's see if ' The $ is inside ! ' ",
" I got $ "].map(check)
);
This can be done using Regular Expressions :
function verify(input)
{
const regex = RegExp(/'.*?\$.*?'/);
return regex.test(input);
}
var str = " Verify '$' "
var str2 = " Let's see if ' The $ is inside ! ' "
var str3 = " I got $ "
console.log(verify(str)) //=> true
console.log(verify(str2)) //=> true
console.log(verify(str3)) //=> false
/'.*?\$.*?'/ pattern description :
' matches the character ' literally (case sensitive)
.*? matches any character (except for line terminators)
*? Quantifier — Matches between zero and unlimited times, as few times as possible, expanding as needed (lazy)
\$ matches the character $ literally (case sensitive)
.*? matches any character (except for line terminators)
*? Quantifier — Matches between zero and unlimited times, as few times as possible, expanding as needed (lazy)
' matches the character ' literally (case sensitive)
Its pretty hard to check if the $ is indeed between two ' and not between a pair of ' a ' and ' b 'b. So I would recommend iterating through the string and toggling a boolean whenever you see a quote. If you find a $ when the boolean is true check if there is a ' in the rest of the text;
console.log(verify("'$'")) //=> true
console.log(verify("' $ '")) //=> true
console.log(verify("'a' $ '")) //=> false
console.log(verify(" ' $ ")) //=> false
function verify(text) {
var openQuotes = false;
for (var index = 0; index < text.length; index++) {
if (text[index] === "'") openQuotes = !openQuotes;
else if (text[index] === "$" && openQuotes && text.indexOf("'", index) !== -1) return true;
}
return false;
}

Regex to match string separated by dots, can only contain alphanumeric, hypens, underscores, dots

I need a regex that will match the following:
a.b.c
a0.b_.c
a.bca._cda.dca-fb
Notice that it can contain numbers, but the groups are separeted by dots. The characters allowed are a-zA-z, -, _, 0-9
The rule is that it cannot start with a number, and it cannot end with a dot. i.e, the regex should not match
0a.b.c
a.b.c.d.
I have come up with a regex, which seems to work on regex101, but not javascript
([a-zA-Z]+.?)((\w+).)*(\w+)
`
But does not seem to work in js:
var str = "a.b.c"
if (str.match("([a-zA-Z]+.?)((\w+).)*(\w+)")) {
console.log("match");
} else {
console.log("not match");
}
// says not match
Your regex matches your values if you use anchors to assert the start ^ and the end $ of the line.
As an alternative you might use:
^[a-z][\w-]*(?:\.[\w-]+)*$
This will assert the start of the line ^, matches a word character \w (which will match [a-zA-Z0-9_]) or a hyphen in a character class [\w-].
Then repeat the pattern that will match a dot and the allowed characters in the character class (?:\.[\w-]+)* until the end of the line $
const strings = [
"a.b.c",
"A.b.c",
"a0.b_.c",
"a.bca._cda.dca-fb",
"0a.b.c",
"a.b.c.d."
];
let pattern = /^[a-z][\w-]*(?:\.[\w-]+)*$/i;
strings.forEach((s) => {
console.log(s + " ==> " + pattern.test(s));
});
If the match should not start with a digit but can start with an underscore or hypen you might use:
^[a-z_-][\w-]*(?:\.[\w-]+)*$
Use forward slashes / and paste the regex code between them from online regex testers, when you use JavaScipt.
Here are, what I've changed in your regex pattern:
added ^ at the beginning of your regex to match the beginning of the input
added $ at the end to match the end of the input
removed A-Z and added the i modifier for case-insensitive search (this is optional).
Also, when you use regex101, make sure to select JavaScript Flavor, when creating/testing your regex for JavaScript.
var pattern = /^([a-z]+.?)((\w+).)*(\w+)$/i;
// list of strings, that should be matched
var shouldMatch = [
'a.b.c',
'a0.b_.c',
'a.bca._cda.dca-fb'
];
// list of strings, that should not be matched
var shouldNotMatch = [
'0a.b.c',
'a.b.c.d.'
];
shouldMatch.forEach(function (string) {
if (string.match(pattern)) {
console.log('matched, as it should: "' + string + '"');
} else {
console.log('should\'ve matched, but it didn\'t: "' + string + '"');
}
});
shouldNotMatch.forEach(function (string) {
if (!string.match(pattern)) {
console.log('didn\'t match, as it should: "' + string + '"');
} else {
console.log('shouldn\'t have matched, but it did: "' + string + '"');
}
});
More on regexes in JavaScript

Handle exceptions in a function that converts a camelCase string to a Formated String in Javascript

So, I've made a function that converts a camelCasedString to a Properly Formatted String using some answer here on Stack Overflow.
This is the function:
function camelCaseToString(str){
var a = str.replace( /([A-Z])/g, " $1" );
var b = a.charAt(0).toUpperCase() + a.slice(1);
return b;
}
problem is some outputs are not as I expect them to be, for example, these are wright:
camelCaseToString('exampleText'); // Example Text
camelCaseToString('ExampleText'); // Example Text
camelCaseToString('string(parenthesis)'); //String (parenthesis)
but I expect these:
camelCaseToString('string (Parenthesis)'); //gives String ( Parenthesis)
camelCaseToString('exampleWithRomanNumbersIII'); //gives Example With Roman Numbers I I I
to be String (Parenthesis) and Example With Roman Numbers III respectively.
Is there a way to to this with Regex? For the parenthesis case, I can simply use replace('( ', '('), but how about the I I I. I need to detect if the Uppercase letters are 1 char long.
I think that this should be really easy to do with Regex but I don't know how to do it. Thanks in advance!
For your specific test cases this seems to work:
function camelCaseToString(str){
var a = str.replace( /([^A-Z( ]+)([A-Z(])/g, "$1 $2" );
var b = a.charAt(0).toUpperCase() + a.slice(1);
return b;
}
You can do it with:
str.replace( /(\(?[A-Z][A-Za-z])/g, " $1" );
A more generic approach will be to match cases when there is a lowercase letter followed with an uppercase one (([a-z])([A-Z])) or (|) when there is start of string position or a non-word char before a lowercase char (\b([a-z])):
function camelCaseToString(str){
var rx = /([a-z])([A-Z])|\b([a-z])/g;
var a = str.replace(rx, function($0, $1, $2, $3, $4) {
return $1 ? $1 + " " + $2 : $3.charAt(0).toUpperCase() + $3.slice(1);
} );
return a;
}
console.log(camelCaseToString('exampleText'));
console.log(camelCaseToString('ExampleText'));
console.log(camelCaseToString('string(parenthesis)'));
console.log(camelCaseToString('string (Parenthesis)'));
console.log(camelCaseToString('exampleWithRomanNumbersIII'));
The match is passed to the replace callback method, and if Group 1 matched, the space is inserted between the lowercase letter ($1) and the uppercase one ($2) (see $1 ? $1 + " " + $2) and when Group 1 did not match (meaning Group 3 matched, a lowercase ASCII letter after a word boundary), the first letter is turned uppercase (see : $3.charAt(0).toUpperCase() + $3.slice(1)).

Regex to match all words but the one beginning and ending with special chars

I'm struggling with a regex for Javascript.
Here is a string from which I want to match all words but the one prefixed by \+\s and suffixed by \s\+ :
this-is my + crappy + example
The regex should match :
this-is my + crappy + example
match 1: this-is
match 2: my
match 3: example
You can use the alternation operator in context placing what you want to exclude on the left, ( saying throw this away, it's garbage ) and place what you want to match in a capturing group on the right side.
\+[^+]+\+|([\w-]+)
Example:
var re = /\+[^+]+\+|([\w-]+)/g,
s = "this-is my + crappy + example",
match,
results = [];
while (match = re.exec(s)) {
results.push(match[1]);
}
console.log(results.filter(Boolean)) //=> [ 'this-is', 'my', 'example' ]
Alternatively, you could replace between the + characters and then match your words.
var s = 'this-is my + crappy + example',
r = s.replace(/\+[^+]*\+/g, '').match(/[\w-]+/g)
console.log(r) //=> [ 'this-is', 'my', 'example' ]
As per desired output. Get the matched group from index 1.
([\w-]+)|\+\s\w+\s\+
Live DEMO
MATCH 1 this-is
MATCH 2 my
MATCH 3 example

Regex that matches anything except for all whitespace

I need a (javascript compliant) regex that will match any string except a string that contains only whitespace. Cases:
" " (one space) => doesn't match
" " (multiple adjacent spaces) => doesn't match
"foo" (no whitespace) => matches
"foo bar" (whitespace between non-whitespace) => matches
"foo " (trailing whitespace) => matches
" foo" (leading whitespace) => matches
" foo " (leading and trailing whitespace) => matches
This looks for at least one non whitespace character.
/\S/.test(" "); // false
/\S/.test(" "); // false
/\S/.test(""); // false
/\S/.test("foo"); // true
/\S/.test("foo bar"); // true
/\S/.test("foo "); // true
/\S/.test(" foo"); // true
/\S/.test(" foo "); // true
I guess I'm assuming that an empty string should be consider whitespace only.
If an empty string (which technically doesn't contain all whitespace, because it contains nothing) should pass the test, then change it to...
/\S|^$/.test("  ");      // false
/\S|^$/.test(""); // true
/\S|^$/.test(" foo "); // true
Try this expression:
/\S+/
\S mean any non-whitespace character.
/^\s*\S+(\s?\S)*\s*$/
demo :
var regex = /^\s*\S+(\s?\S)*\s*$/;
var cases = [" "," ","foo","foo bar","foo "," foo"," foo "];
for(var i=0,l=cases.length;i<l;i++)
{
if(regex.test(cases[i]))
console.log(cases[i]+' matches');
else
console.log(cases[i]+' doesn\'t match');
}
working demo : http://jsfiddle.net/PNtfH/1/
[Am not I am]'s answer is the best:
/\S/.test("foo");
Alternatively you can do:
/[^\s]/.test("foo");
if (myStr.replace(/\s+/g,'').length){
// has content
}
if (/\S/.test(myStr)){
// has content
}

Categories

Resources