RegExp: Match '3' words of a list, not repeating - javascript

I'm doing an applications in which the user is asked to write, for example, three words of a list (the order is not important).
I can try something like this:
\^ [ itemA | itemB | itemC | itemD | item E | item F] {3}
But obviously, the user can write three times the same item. Is there a way to archieve it using a regular expression and evaluate it using a single "match" function?
I'm using JavaScript, of course.
Thank you guys!
Excuse me, let me clarify.
I have the following screen:
So the user have 7 possible answers, and he have to write three of them.
Of course, this "screen" have a LOT of kind of questions in which a regex worked very well to evaluate it, but in this one, I don't know if it is enought.
Thank you guys.

To check that I've understood, you're attempting to validate that:
The user has entered exactly three items,
Each item is a member of a pre-defined list
And each item is unique?
That's not a good fit for a regular expression. You can meet the first two requirements, but it's much simpler to do the third one directly using JavaScript or something similar.
If you really want to do it this way, you can do this:
^(itemA|itemB|itemC|itemD|item E|itemF) (?!\1)(itemA|itemB|itemC|itemD|item E|itemF) (?!\1)(?!\2)(itemA|itemB|itemC|itemD|item E|itemF)
This uses a negative lookahead:
First item must match itemA-itemF
Second item must first not match whatever the first item was, and also match itemA-itemF
Third item must not match the first item, not match the second item, and also match itemA-itemF.

Related

regex pattern a then b then a, one or more times

I want to use regex to find a repeating pattern but I can't work out how to do it. I want to get all matches where there is a number then a plus symbol then another number, including repeats.
So for example, if the string is "5+2-6+10+3", I want to end up with ["5+2", "6+10+3"]
So far I've got
\d*\+\d*
But that doesn't capture the final "+3" in the example above. I had a few attempts using brackets for capturing groups but I couldn't get the output I wanted.
Any help would be much appreciated!
Solved using the following (thanks The fourth bird):
\d+(?:\+\d+)+

Matching varying length in JS Regex

Let me explain my query with an example:
Am capturing page name from a web site. Due to design, the page name can be of varying length:
It can be
Data1|Data2|Data3
Data1|Data2|Data3|Data4
Data1|Data2
I need to write a Regex which comes true on all the above scenarios. I have something below shared by a previous user:
/(.*?)\|(.*?)\|(.*?)\|(.*)/gm;
The above works well when the string is always of four group, and there is a blank in between. But if I just have two values the regex fails. Can any user please guide?
Not sure what you meant there but does this help? But it will only accept alphanumeric values and a space
/([a-zA-Z 0-9]{1,}\|){1,}[a-zA-Z 0-9]{1,}/g
This will expect at less two Data field, and at most 4 fields
/(?:([^|]*)\|){1,3}([^|]*)/gm;
If you also want only one field (no pipe):
/(?:([^|]*)\|){,3}([^|]*)/gm;
{n,m} means allowed to repeat n trhough m times
Notice how I used [^|]* instead of .*?, so I match anything but the pipe |, also I used non matching groups (?:) so the groups that includes the pipes are invisible, i.e. you can get the fields as get them before

How can I match strings precisely and avoid false matches?

Background - web app back end javascript/dojo code.
I need to match a user input string to a list of possible vehicle models and I am having challenges with incorrect matches.
Say a user enters:
Ford Fusion, S 60, and Volks Wagen
Currently, I would read that in as
FORDFUSIONS60VOLKSWAGEN
and in that, I would match against a list of makes and models.
Problem is, in this case and in many others, you get things like "S6" (Audi) " and "S60" (Volvo), or "Accord" (Honda) or "CC" (Volkswagen).
Any idea how it would be possible (if at all) to avoid these ambiguous matches?
Since this question is tagged regex, I think you are looking for the word boundary metacharacter:
/\bS6\b/
will match "S6" and "… S6 …", but not "S60", just as
/\bCC\b/i
will match "CC" and "cc", but not "Accord".
To avoid at least the both examples you would first match against the longer names (e.g. for "s60" before "s6" and "accord" before "cc") and if there's no match, then use the shorter one. Otherwise exit with the longer one.
As far as you're looking for the longest matches, you also could check, if one of the resulting names is contained within another and skip them.
This is how I would go about it:
Run checks with the name, model and company and if they trace back to the same reference, then you know you have what you want. However, if you get different results keep trying combinations of all search results until they match up to a single reference.
For example:
model traces back to honda and ford,
number traces back to ford and bentley,
and
company gives ford
then you can try combinations of list_1, list_2, and list_3 where:
list_1 = ['honda','ford']
list_2 = ['ford','bentley']
list_3 = ['ford']
Then when you try all combinations (I recommend itertools.combinations) you will end up with one valid result that is common in all lists: ford
I hope that is clear. I know I'm blabbing a bit.

Split By 2 String Delimiters via RegEx Javascript

I am relatively new to RegEx and need help splitting up a section of text by two delimiters, and then capturing what's between them. For instance, I have a JSON object that has a "description" property, and it essentially contains this text:
This is yet another test product to test for all sorts of styling/formatting issues.
PLACEHOLDER
PLACEHOLDER
PLACEHOLDER
******
Not so expensive
Works all day
Works throughout the night
No risk
100% Guarantee
------
This would be where ingredients would go for Test Product 4.
What I am trying to do is to capture the "bulleted" list between the six-asterisk delimiter and the 6-dash delimiter. So in the above example, I want to be able to capture these lines:
Not so expensive
Works all day
Works throughout the night
No risk
100% Guarantee
Thus, I need to split by two delimiters:
1) ******
2) ------
After searching around this and other forums, I still can't seem to get any form of .split() method and RegEx to get precisely what I want. Is anyone able to help me out here? The ultimate goal is to be able to capture that text and then append it to a <div>
No? Really?
string.split(/------|\*\*\*\*\*\*/);

match text between two html custom tags but not other custom tags

I have something like the following;-
<--customMarker>Test1<--/customMarker>
<--customMarker key='myKEY'>Test2<--/customMarker>
<--customMarker>Test3 <--customInnerMarker>Test4<--/customInnerMarker> <--/customMarker>
I need to be able to replace text between the customMarker tags, I tried the following;-
str.replace(/<--customMarker>(.*?)<--\/customMarker>/g, 'item Replaced')
which works ok. I would like to also ignore custom inner tags and not match or replace them with text.
Also I need a separate expression to extract the value of the attribute key='myKEY' from the tag with Text2.
Many thanks
EDIT
actually I am trying to find things between comment tags but the comment tags were not displaying correctly so I had to remove the '!'. There's a unique situation that required comment tags... in anycase if anyone knows enough regex to help, it would be great. thank u.
In the end, I did something like the following (incase anyone else needs this. enjoy!!! But note: Word about town is that using regex with html tags is not ideal, so do your own research and make up your mind. For me, it had to be done this way, mostly bcos i wanted to, but also bcos it simplified the job in this instance);-
var retVal = str.replace(/<--customMarker>(.*?)<--\/customMarker>/g, function(token, match){
//question 1: I would like to also ignore custom inner tags and not match or replace them with text.
//answer:
var replacePattern = /<--customInnerMarker*?(.*?)<--\/customInnerMarker-->/g;
//remove inner tags from match
match = $.trim(match.replace(replacePattern, ''));
//replace and return what is left with a required value
return token.replace(match, objParams[match]);
//question 2: Also I need a separate expression to extract the value of the attribute key='myKEY' from the tag with Text2.
//answer
var attrPattern = /\w+\s*=\s*".*?"/g;
attrMatches = token.match(attrPattern);//returns a list of attributes as name/value pairs in an array
})
Can't you use <customMarker> instead? Then you can just use getElementsByTagName('customMarker') and get the inner text and child elements from it.
A regex merely matches an item. Once you have said match, it is up to you what you do with it. This is part of the problem most people have with using regular expressions, they try and combine the three different steps. The regex match is just the first step.
What you are asking for will not be possible with a single regex. You're going to need a mini state machine if you want to use regular expressions. That is, a logic wrapper around the matches such that it moves through each logical portion.
I would advise you look in the standard api for a prebuilt engine to parse html, rather than rolling your own. If you do need to do so, read the flex manual to get a basic understanding of how regular expressions work, and the state machines you build with them. The best example would be the section on matching multiline c comments.

Categories