I have the following string: aaabaaa
I want to match the following pattern: aba, aabaa, aaabaaa
Right now I have the following regex pattern: /(([a-z])\2*)((?!\2)[a-z])\1/g
It only matches aaabaaa but not the other ones. The pattern has to work for all characters and the characters can be surrounded by other characters.
Works for:
'mnonnopoo' -> ['non', 'opo']
'asasd' -> ['asa']
Doesn't work for:
'aaaasaaaaa' -> ['asa', 'aasaa', 'aaasaaa', 'aaaasaaaa']
'aaabaazsaaasbbabba' -> ['aba', 'aabaa', 'bab', 'bbabb']
regexr.com/63igv
As people indicated in the comment, regex don't match multiple times for the same string, not in javascript at least.
If you used the on-greedy regex,
/([a-z])((?!\1)[a-z])\1/g
it would find
'aaaasaaaaa' -> ['asa']
'aaabaazsaaasbbabba' -> ['aba', 'bab']
So you could use greedy regex
/([a-z]*?)((?!\1)[a-z])\1/g
Which would leave you with
'aaaasaaaaa' -> ['aaaasaaaa']
'aaabaazsaaasbbabba' -> ['aabaa', 'bbabb']
Then sub the results recursively to make the following regex:
/(?!.*bbabb.*)(?!.*aabaa.*)(?!.*aaaasaaaa.*)([a-z]*?)((?!\1)[a-z])\1/g
It then matches 'aaasaaa', 'aba', and 'bab' and you simply keep looping till there is no match.
Though I'm sure there are probably better ways to this without regex.
Related
I have a bunch of common regex patterns which I got from here. I try applying them to a string but they do not seem to modify anything. It just returns me the same value. Can you please enlighten me on what I am doing wrong.
const str = 'sadas87676szdhgzshdgszhjg,##%$,.%';
const commonRegexPatterns = {
DIGITS: /^[0-9]+$/,
ALPHABETIC: /^[a-zA-Z]+$/,
ALPHANUMERIC: /^[a-zA-Z0-9]+$/,
DATE: /^(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}$/,
EMAIL: /^[a-zA-Z0-9._%-]+#[a-zA-Z0-9.-]+.[a-zA-Z]{2,4}$/,
ZIP: /^[0-9]{5}(?:-[0-9]{4})?$/,
DIGITSWITHCOMMA: /^[\d,]/,
DIGITSWITHCOMMAPERCENTAGE: /^[\d,%]/,
}
console.log('DIGITS', str.replace(commonRegexPatterns.DIGITS, ''));
console.log('ALPHABETIC', str.replace(commonRegexPatterns.ALPHABETIC, ''));
console.log('ALPHANUMERIC', str.replace(commonRegexPatterns.ALPHANUMERIC, ''));
console.log('DIGITSWITHCOMMA', str.replace(commonRegexPatterns.DIGITSWITHCOMMA, ''));
console.log('DIGITSWITHCOMMAPERCENTAGE', str.replace(commonRegexPatterns.DIGITSWITHCOMMAPERCENTAGE, ''));
console.log('ZIP', str.replace(commonRegexPatterns.ZIP, ''));
Well, your regex patterns are wrong. Ok, not really "wrong", but they are not what you seem to want. For example, DIGITS:
^[0-9]+$
This pattern has anchors (the ^ is the start of the string, the $ is the end). It will match an entire string of numbers, but not just any number inside a string. For your purpose, you want it without the anchors, like:
[0-9]+
The same applies to most of the other patterns in your snippet. Remove the anchors if you are just trying to match part of a string.
Additionally, since you seem to be trying to remove all occurrences of patterns in the string, you probably want to use the g flag in your patterns. For example, ALPHABETIC (without the anchors):
/[a-zA-Z]+/
This will match the first group of letters in your string, but not the ones after it. If instead you use
/[a-zA-Z]+/g
You will be able to replace every match.
I am passing a URL to a block of code in which I need to insert a new element into the regex. Pretty sure the regex is valid and the code seems right but no matter what I can't seem to execute the match for regex!
//** Incoming url's
//** url e.g. api/223344
//** api/11aa/page/2017
//** Need to match to the following
//** dir/api/12ab/page/1999
//** Hence the need to add dir at the front
var url = req.url;
//** pass in: /^\/api\/([a-zA-Z0-9-_~ %]+)(?:\/page\/([a-zA-Z0-9-_~ %]+))?$/
var re = myregex.toString();
//** Insert dir into regex: /^dir\/api\/([a-zA-Z0-9-_~ %]+)(?:\/page\/([a-zA-Z0-9-_~ %]+))?$/
var regVar = re.substr(0, 2) + 'dir' + re.substr(2);
var matchedData = url.match(regVar);
matchedData === null ? console.log('NO') : console.log('Yay');
I hope I am just missing the obvious but can anyone see why I can't match and always returns NO?
Thanks
Let's break down your regex
^\/api\/ this matches the beginning of a string, and it looks to match exactly the string "/api"
([a-zA-Z0-9-_~ %]+) this is a capturing group: this one specifically will capture anything inside those brackets, with the + indicating to capture 1 or more, so for example, this section will match abAB25-_ %
(?:\/page\/([a-zA-Z0-9-_~ %]+)) this groups multiple tokens together as well, but does not create a capturing group like above (the ?: makes it non-captuing). You are first matching a string exactly like "/page/" followed by a group exactly like mentioned in the paragraph above (that matches a-z, A-Z, 0-9, etc.
?$ is at the end, and the ? means capture 0 or more of the precending group, and the $ matches the end of the string
This regex will match this string, for example: /api/abAB25-_ %/page/abAB25-_ %
You may be able to take advantage of capturing groups, however, and use something like this instead to get similar results: ^\/api\/([a-zA-Z0-9-_~ %]+)\/page\/\1?$. Here, we are using \1 to reference that first capturing group and match exactly the same tokens it is matching. EDIT: actually, this probably won't work, since the text after /api/ and the text after /page/ will most likely be different, carrying on...
Afterwards, you are are adding "dir" to the beginning of your search, so you can now match someting like this: dir/api/abAB25-_ %/page/abAB25-_ %
You have also now converted the regex to a string, so like Crayon Violent pointed out in their comment, this will break your expected funtionality. You can fix this by using .source on your regex: var matchedData = url.match(regVar.source); https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/source
Now you can properly match a string like this: dir/api/11aa/page/2017 see this example: https://repl.it/Mj8h
As mentioned by Crayon Violent in the comments, it seems you're passing a String rather than a regular expression in the .match() function. maybe try the following:
url.match(new RegExp(regVar, "i"));
to convert the string to a regular expression. The "i" is for ignore case; don't know that's what you want. Learn more here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
Hello to the community I have a query, I need a validation Regex, for amounts without decimals, that consider valid the following structure.
99,999,999
If I add a value:
12345678 -> Ok
12,345,678 -> Ok
123,456,789 -> Failed
123,45,6,78 -> Failed
12,345,678.50 -> Failed
12,456,7ab -> Failed
I have only been able to validate the size of 8 numerical characters:
var regex8 = /^-?([0-9]{1,8})?$/;
I wait for your comments.
Thank you.
With a bit of work you can craft a pattern to do this:
https://regex101.com/r/DKpSUR/1
/^-?([0-9]{1,2},?)?([0-9]{3},?){1,2}$/
This regex should supply you with what you want or point you in a direction:
-?([0-9]{1,2},)?([0-9]{3},)?[0-9]{3}
This will match an optional leading sign [-+]?
followed by either
a string of one or more digits \d+ or
a 1-3 digit string \d{1,3} followed by one more more groups of comma-3-digits ,\d{3}
Putting it all together:
/^[-+]?((\d+)|(\d{1,3}(,\d{3})+))$/
I have grouped them with parentheses () to make it clear, but be aware this creates capturing groups.
var rgx = /^[-+]?((\d+)|(\d{1,3}(,\d{3})+))$/
var matched = "+813,823".match(rgx); // ==> ["+813,823", "813,823", undefined, "813,823", ",823"]
You would want matched[0] to get the whole match.
I have string patterns like name1|value1, name1|value1,name2|value2, name1| and name1|value1,. I have to have Regular expression to find the given pattern is true or false
Input and output would be
"name1|value1" -> true
"name1|value1,name2|value2" -> true
"name1|" -> false
"name1|value1," -> false
"name1|value1,name2" -> false
"name1|value1,name2|" -> false
Pretty simple: ^\w+\|\w+(,\w+\|\w+)*$
The first portion, ^\w+\|\w+ looks to make sure the string starts with at least 1 completed name|value pair.
Then the second portion, (,\w+\|\w+)* says that same pattern may repeat infinitely as long as there is a comma between the first pair and all subsequent pairs. (Although, the asterisk quantifies that the second portion of the pattern may not occur at all.)
Finally the $ says that the string must end matching this pattern. (I.e., this pattern cannot only match part of the string. It must match the entire string because of the ^ and $.)
To format this pattern for javascript, simply throw a forward slashes on both ends, so: /^\w+\|\w+(,\w+\|\w+)*$/ The pattern should not require any flags.
It is worth noting, if you need to match more complex names/values that are outside the character range of \w, then you should replace all \ws with [Some Character Set(s)].
If your have multiple pairs to check, you can apply your regex on splitted string elements with an every function:
isValidPairs = function(str) {
return str.split(',').every(function(elt) {
return /^\w+\|\w+$/.test(elt);
});
}
pairsArr = ["nam1|val1", "nam1|val1,name2|val2", "nam1|", "nam1|val1,", "nam1|val1,name", "nam1|val1,name|"];
pairsArr.forEach(function(str) {
console.log('%s: %s:', str, isValidPairs(str));
});
I was given a task to do which requires a long time to do.
The image say it all :
This is what I have : (x100 times):
And I need to extract this value only
How can I capture the value ?
I have made it with this regex :
DbCommand.*?\("(.*?)"\);
As you can see it does work :
And after the replace function (replace to $1) I do get the pure value :
but the problem is that I need only the pure values and not the rest of the unmatched group :
Question : In other words :
How can I get the purified result like :
Eservices_Claims_Get_Pending_Claims_List
Eservices_Claims_Get_Pending_Claims_Step1
Here is my code at Online regexer
Is there any way of replacing "all besides the matched group" ?
p.s. I know there are other ways of doing it but I prefer a regex solution ( which will also help me to understand regex better)
Unfortunately, JavaScript doesn't understand lookbehind. If it did, you could change your regular expression to match .*? preceded (lookbehind) by DbCommand.*?\(" and followed (lookahead) by "\);.
With that solution denied, i believe the cleanest solution is to perform two matches:
// you probably want to build the regexps dynamically
var regexG = /DbCommand.*?\("(.*?)"\);/g;
var regex = /DbCommand.*?\("(.*?)"\);/;
var matches = str.match(regexG).map(function(item){ return item.match(regex)[1] });
console.log(matches);
// ["Eservices_Claims_Get_Pending_Claims_List", "Eservices_Claims_Get_Pending_Claims_Step1"]
DEMO: http://jsbin.com/aqaBobOP/2/edit
You should be able to do a global replace of:
public static DataTable.*?{.*?DbCommand.*?\("(.*?)"\);.*?}
All I've done is changed it to match the whole block including the function definition using a bunch of .*?s.
Note: Make sure your regex settings are such that the dot (.) matches all characters, including newlines.
In fact if you want to close up all whitespace, you can slap a \s* on the front and replace with $1\n:
\s*public static DataTable.*?{.*?DbCommand.*?\("(.*?)"\);.*?}
Using your test case: http://regexr.com?37ibi
You can use this (without the ignore case and multiline option, with a global search):
pattern: (?:[^D]+|\BD|D(?!bCommand ))+|DbCommand [^"]+"([^"]+)
replace: $1\n
Try simply replacing the whole document replacing using this expression:
^(?: |\t)*(?:(?!DbCommand).)*$
You will then only be left with the lines that begin with the string DbCommand
You can then remove the spaces in between by replacing:
\r?\n\s* with \n globally.
Here is an example of this working: http://regexr.com?37ic4