I was trying to match the ordered letters using regular expression in php/javascript.
I have a 4 letter word in which first 2 letters should be in order and the next two letters should be in order like BCEF. This I wanted to match using regular expression.
But the below regular expression is also matching the order CBFE
Please suggest what's missing in the below expression to match the letters order. Thank you.
[A-H]{2}[D-M]{2}
I would not use a regex but php code instead :
$s = "BCEF";
$arr = str_split($s);
if ($arr[0] <= $arr[1] && $arr[2] <= $arr[3]) {
// Your string matched
}
Here's a solution using regex (but mainly to illustrate how stupid it is ;).
(?:A[B-H]|B[C-H]|B[C-H]|D[E-H]|E[FGH]|F[GH]|GH)(?:D[E-M]|E[F-M]|F[G-M]|G[H-M]|H[I-M]|I[J-M]|J[KLM]|LM)
It has two (non capturing) groups following one another - one for each letter pair.
They tests for all possible start characters (A to G for the first pair and D to L for the second) being followed by any of the allowed subsequent characters, using alternation.
See it here at regex101.
Related
I have an input string like this:
ABCDEFG[HIJKLMN]OPQRSTUVWXYZ
How can I replace each character in the string between the [] with an X (resulting in the same number of Xs as there were characters)?
For example, with the input above, I would like an output of:
ABCDEFG[XXXXXXX]OPQRSTUVWXYZ
I am using JavaScript's RegEx for this and would prefer if answers could be an implementation that does this using JavaScript's RegEx Replace function.
I am new to RegEx so please explain what you do and (if possible) link articles to where I can get further help.
Using replace() and passing the match to a function as parameter, and then Array(m.length).join("X") to generate the X's needed:
var str = "ABCDEFG[HIJKLMN]OPQRSTUVWXYZ"
str = str.replace(/\[[A-Z]*\]/g,(m)=>"["+Array(m.length-1).join("X")+"]")
console.log(str);
We could use also .* instead of [A-Z] in the regex to match any character.
About regular expressions there are thousands of resources, specifically in JavaScript, you could see Regular Expressions MDN but the best way to learn, in my opinion, is practicing, I find regex101 useful.
const str="ABCDEFG[HIJKLMN]OPQRSTUVWXYZ";
const run=str=>str.replace(/\[.*]/,(a,b,c)=>c=a.replace(/[^\[\]]/g,x=>x="X"));
console.log(run(str));
The first pattern /\[.*]/ is to select letters inside bracket [] and the second pattern /[^\[\]]/ is to replace the letters to "X"
We can observe that every individual letter you wish to match is followed by a series of zero or more non-'[' characters, until a ']' is found. This is quite simple to express in JavaScript-friendly regex:
/[A-Z](?=[^\[]*\])/g
regex101 example
(?= ) is a "positive lookahead assertion"; it peeks ahead of the current matching point, without consuming characters, to verify its contents are matched. In this case, "[^[]*]" matches exactly what I described above.
Now you can substitute each [A-Z] matched with a single 'X'.
You can use the following solution to replace a string between two square brackets:
const rxp = /\[.*?\]/g;
"ABCDEFG[HIJKLMN]OPQRSTUVWXYZ".replace(rxp, (x) => {
return x.replace(rxp, "X".repeat(x.length)-2);
});
I need two regular expression.
1) Any characters followed by a comma followed by any characters followed by a comma followed by any characters.
Currently I have:
/(.*,.*,.*)/
2) Any characters followed by a comma followed by any characters so long as they are not a comma.
Currently I have:
/(.*,.*[^,]+.*)/
Any help would be much appreciated. Thanks in advance!
For your first Regex you could really just use Javascript built in string.split(","); Which would return an array of strings. From there run a check for array.length >= 3 and you'll know the string matched you pattern. That being said f there are commas in the characters after that second required comma you could have issues depending on what you are expecting.
The second Regex could be verified using string.split(",") as well. Your second check would just be array.length === 2
The full code would be something like this
function verify(str) {
var arr = str.split(",");
if (arr.length < 2)
return "Invalid string provided";
if (arr.length === 2)
return arr[0] + arr[1];
return join(arr);
}
verify("some,crazy,comma delimited voodoo");
For your first regular expression, /(.*,.*,.*)/, you have what you're looking for. Note that "any character" includes commas, so really this only guarantees that there will be at least 2 commas.
For the second, /(.*,.*[^,]+.*)/, that's not quite right. "Any characters followed by a comma followed by any characters so long as they are not a comma" would be /(.*,[^,]*)/. However again, consider that "any characters" includes commas, so it is somewhat meaningless.
Perhaps you mean something more like /([^,]*,[^,]*)/? This is any text with precisely one comma. You can repeat the pattern by adding a second ,[^,]* as you wish, for example /([^,]*,[^,]*,[^,]*)/ is for precisely two commas.
If you wish to match any number of items separated by commas, try /([^,]+,?)/g to match each individual list item.
If you also require that there is text between commas, use + instead of *.
I don't know the utility of your regular expressions but in the linux grep command this will work:
grep '?,?,?'
grep '?,*[^,]'
I am trying to use regexp to match some specific key words.
For those codes as below, I'd like to only match those IFs at first and second line, which have no prefix and postfix. The regexp I am using now is \b(IF|ELSE)\b, and it will give me all the IFs back.
IF A > B THEN STOP
IF B < C THEN STOP
LOL.IF
IF.LOL
IF.ELSE
Thanks for any help in advance.
And I am using http://regexr.com/ for test.
Need to work with JS.
I'm guessing this is what you're looking for, assuming you've added the m flag for multiline:
(?:^|\s)(IF|ELSE)(?:$|\s)
It's comprised of three groups:
(?:^|\s) - Matches either the beginning of the line, or a single space character
(IF|ELSE) - Matches one of your keywords
(?:$|\s) - Matches either the end of the line, or a single space character.
Regexr
you can do it with lookaround (lookahead + lookbehind). this is what you really want as it explicitly matches what you are searching. you don't want to check for other characters like string start or whitespaces around the match but exactly match "IF or ELSE not surrounded by dots"
/(?<!\.)(IF|ELSE)(?!\.)/g
explanation:
use the g-flag to find all occurrences
(?<!X)Y is a negative lookbehind which matches a Y not preceeded by an X
Y(?!X) is a negative lookahead which matches a Y not followed by an X
working example: https://regex101.com/r/oS2dZ6/1
PS: if you don't have to write regex for JS better use a tool which supports the posix standard like regex101.com
I'm trying to build up a regex pattern for the html input field which only allows up to 20 combined alphabetical letters and digits which can only have up to two of Dashes(-), Underscores(_) and fullstops (.)
So something like only two of the symbols allowed and any amount of letters and digits allowed, combined they've got to be between 4 and 20.
What would the pattern for this be?
An sample (non functioning) version could be like [A-Za-z0-9([\._-]{0,2})]{4,20}
Solution:
I decided to go with #pascalhein #Honore Doktorr answer which is to use a lookahead.
The final pattern is ^(?=[A-Za-z0-9]*([._-][A-Za-z0-9]*){0,2}$)[A-Za-z0-9._-]{4,20}$
You can verify the length with a lookahead at the beginning:
^(?=.{4,20}$)
Then list all the cases that are allowed for your regex separately:
[A-Za-z0-9]* (no special chars)
[A-Za-z0-9]*[._-][A-Za-z0-9]* (one special char)
[A-Za-z0-9]*[._-][A-Za-z0-9]*[._-][A-Za-z0-9]* (two special chars)
It isn't beautiful, but I believe it should work. This is the final expression:
^(?=.{4,20}$)([A-Za-z0-9]*|[A-Za-z0-9]*[._-][A-Za-z0-9]*|[A-Za-z0-9]*[._-][A-Za-z0-9]*[._-][A-Za-z0-9]*)$
Edit:
Actually, it might be nicer to test the number of special characters with a lookahead instead:
^(?=[A-Za-z0-9]*([._-][A-Za-z0-9]*){0,2}$)[A-Za-z0-9._-]{4,20}$
I encourage you to not to use a Regex when there are functions for the porpuse you want to achieve.
An advice I give to jrs on this topic is to use a regex for single porpuses, if there is more than one porpuse, use more regex.
to answer your question:
1 your valid characters from start to end.
var 1stregex = /^[A-Za-z0-9._-]{4,20}$/;
2 Count must be 0 to 2, which in javascript is .match().length.
var 2ndregex = /([._-])/;
if(myText.match(1stregex) && myText.match(2ndregex).length <=2)
{ isvalid=true; }
I have string with 2 or 3 words:
'apple grape lemon'
'apple grape'
I need to get first char from all words.
my regex:
/^(\w).*?\ (\w).*?\ ?(\w?).*?$/
For all strings this regex get only first char of 2 words.
How to fix?
You cannot do this with one regex (unless you are using .NET). But you can use a regex that matches one first character of a word, then get all the matches, and join them together:
var firstLetters = '';
var match = str.match(/\b\w/g)
if (match)
firstLetters = match.join('');
Of course if you just want to get the letters on their own, there is no need for the join, since the match will simply be an array containing all those letters.
You should not, that \w is not only letters, but digits and underscores, too.
If you work with javascript, you don't need to regex the hell out of a simple problem.
To get the first letter, just do that:
var aString = 'apple bee plant';
var anArray = aString.split(' ');
for(var aWord in anArray) {
var firstLetter = aWord.charAt(0);
}
Regular expressions are a regular language, such that you cannot have this kind of repetition in them. What you want is to cut the string into individual tokes (which can be done via regular expressions to match the separator) and then apply an regular expression on each token. To get the first char from each word it is faster to use a substring operation instead of a regular expression.
The problem with your regex is that the .*? after the second word eats up all the following content as everything afterwards is optional. This could be solved, but I personally think it makes things more complicated than required.
The most simple way would be:
firstLetters = (m = str.match(/\b\w/g))? m.join('') : '';
In regexp "words" don't mean only letters. In JavaScript \w is equals [A-Za-z0-9_]. So if you want only letters in your result, you can use [A-Za-z].