JavaScript RegEx - Minimum characters with Wildcard - javascript

I'm working on matching a wildcard search input. it's a name field.
Below are the conditions I need to match.
User must enter at least 3 alphanumeric characters, if he chooses to do a Wildcard search
User may/maynot enter a wildcard at the start or end of the string,but it can be on either side.
Allow spaces between words.
I want to mention that i'm trimming the string before doing a match. This is what I tried so far.
^[^\W_](\s?\w?)*$|^[^\W_]{3,}(\s?\w?)*\*$|^[\*][^\W_]{3,}(\s?\w?)*$
Debuggex Demo
Below are some examples I tried -
someone xxx, someone xxx yyy - Passed
someone* xxx- Failed
someone , someone - Passed
This is the nearest match of what i want- But it fail for these test case.
AB asf* -- Fails , this will pass- ABC asf*
*AB asf -- Fails , this will pass- *ABC asf
I know I have a condition that says - starts with at least 3 alphanumeric character and repeat space and alphanumeric characters.
That's where I need help with.
Thanks.

UPDATE2 This pattern should do:
/^([a-zA-Z0-9]{3,}[^\n*]*\*?|\*[a-zA-Z0-9]{2,}[^\n*]*|[a-zA-Z0-9]{2}\*)$/gm
EXPLANATION:
^ # assert start of line
( # 1st capturing group starts
[a-zA-Z0-9]{3,} # match 3+ times alphanumeric characters
[^\n*]* # match 0 or more non-newline and non-star (*) characters
\*? # match 0 or one literal star (*) character;
| # OR
\* # match one literal star (*) character
[a-zA-Z0-9]{2,} # match 2+ times alphanumeric characters
[^\n*]* # match 0 or more non-newline and non-star (*) characters;
| # OR
[a-zA-Z0-9]{2} # match 2 non-newline and non-star (*) characters
\* # match one literal star (*) character
) # 1st capturing group ends
$ # assert end of line
REGEX 101 DEMO.

Try this one:
^(?:[^\W_]+|\*[^\W_]{3,}|[^\W_]{3,}\*)(?:\s+(?:[^\W_]+|\*[^\W_]{3,}|[^\W_]{3,}\*))*$
NOTE: using [^\W_] instead of \w just as in your original regex.
regex101
However, I argue that this task cannot be solved in a clean way using a regex. Maybe a proper javascript function would be more readable.

If I understand correctly the requirements,
this might work. It does in my tests.
^(?:\*[^\W_]{3,}(?:\s*[^\W_]\s*)*|(?:\s*[^\W_]\s*)*[^\W_]{3,}\*|(?:\s*[^\W_]\s*)+)$
Expanded
^ # BOS
(?: # One of either ---
\* # Star at beeginning
[^\W_]{3,} # 3 or more words
(?: \s* [^\W_] \s* )* # Any number of word's following spaces
| # or,
(?: \s* [^\W_] \s* )* # Any number of word's following spaces
[^\W_]{3,} # 3 or more words
\* # Star at end
| # or,
(?: \s* [^\W_] \s* )+ # Any number of word's following spaces
) # ---------
$ # EOS

Related

How to match a filename pattern in JavaScript?

How can i match a filename, which is exactly (Capitals included) in the following format/pattern:
yymmdd_Name1_Data_Prices,
yymmdd_Name1_Data_Contact,
yymmdd_Name1_Data_Address.
I have files that need to be uploaded and the filenames are saved in a database. I want to match the given filename, with the pattern from the database, but i am unsure how to do that.
You could use the following regular expression.
\b\d{6}(?:_[A-Z][a-z]+){3}\b
Demo
Javascript's regex engine performs the following operations.
\b # match word break
\d{6} # match 6 digits
(?: # begin non-capture group
_[A-Z][a-z]+ # match '_', one upper-case letter, 1+ lower-case letters
) # end non-capture group
{3} # execute non-capture group 3 times
\b # match word break
Match the first 6 characters, which corresponds to a date, could be more precise than simply matching 6 digits. For example, assuming the year is 2000-2020, one could replace \d{6} with
(?:[01]\d|20)(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|30|31)
but it still does would not ensure the date is valid.

Regex match url with params to specific pattern but not query string

My regex pattern:
const pattern = /^\/(test|foo|bar\/baz|en|ppp){1}/i;
const mat = pattern.exec(myURL);
I want to match:
www.mysite.com/bar/baz/myParam/...anything here
but not
www.mysite.com/bar/baz/?uid=100/..
myParam can be any string with or without dashes but only after that anything else can occur like query strings but not immediately after baz.
Tried
/^\/(test|foo|bar\/baz\/[^/?]*|en|ppp){1}/i;
Nothing works.
This, I believe, is what you are asking for:
const myURL = "www.mysite.com/bar/baz/myParam/";
const myURL2 = "www.mysite.com/bar/baz/?uid=100";
const regex = /\/[^\?]\w+/gm;
console.log('with params', myURL.match(regex));
console.log('with queryParams', myURL2.match(regex))
You can test this and play further in Regex101. Even more, if you use that page, it tells you what does what in the regex string.
If it's not what you were asking for, there was another question related to yours, without regex: Here it is
For the 2 example strings, you might use
^[^\/]+\/bar\/baz\/[\w-]+\/.*$
Regex demo
If you want to use the alternations as well, it might look like
^[^\/]+\/(?:test|foo|bar)\/(?:baz|en|ppp)\/[\w-]+\/.*$
^ Start of string
[^\/]+ Match 1+ times any char except a /
\/ Match /
(?:test|foo|bar) Match 1 of the options
\/ Match /
(?:baz|en|ppp) Match 1 of the options
\/ Match /
[\w-]+ Match 1+ times a word char or -
\/ Match /
.* Match 0+ occurrences of any char except a newline
$ End of string
Regex demo
Using a negative lookahead or lookbehind will solve your problem. There are 2 options not clear from the question:
?uid=100 is not allowed after the starting part /bar/baz, so www.mysite.com/test/bar/baz?uid=100 should be valid.
?uid=100 is not allowed anywhere in the string following /bar/baz, which means that www.mysite.com/test/bar/baz/?uid=100 is invalid as well.
Option 1
In short:
\/(test|foo|bar\/baz(?!\/?\?)|en|ppp)(\/[-\w?=]+)*\/?
Explanation of the important parts:
| # OR
bar # 'bar' followed by
\/ # '/' followed by
baz # 'baz'
(?! # (negative lookahead) so, **not** followed by
\/? # 0 or 1 times '/'
\? # '?'
) # END negative lookahead
and
( # START group
\/ # '/'
[-\w?=]+ # any word char, or '-','?','='
)* # END group, occurrence 0 or more times
\/? # optional '/'
Examples Option 1
You can make the lookahead even more specific with something like (?!\/?\?\w+=\w+) to make explicit that ?a=b is not allowed, but that's up to you.
Option 2
To make explicit that ?a=b is not allowed anywhere we can use negative lookbehind. Let's first find a solution for not allowing* bar/baz preceding the ?a=b.
Shorthand:
(?<!bar\/baz\/?)\?\w+=\w+
Explanation:
(?<! # Negative lookbehind: do **not** match preceding
bar\/baz # 'bar/baz'
\/? # optional '/'
)
\? # match '?'
\w+=\w+ # match e.g. 'a=b'
Let's make this part of the complete regex:
\/(test|foo|en|ppp|bar\/baz)(\/?((?<!bar\/baz\/?)\?\w+=\w+|[-\w]+))*\/?$
Explanation:
\/ # match '/'
(test|foo|en|ppp|bar\/baz) # start with 'test', 'foo', 'en', 'ppp', 'bar/baz'
(\/? # optional '/'
((?<!bar\/baz\/?)\?\w+=\w+ # match 'a=b', with negative lookbehind (see above)
| # OR
[-\w]+) # 1 or more word chars or '-'
)* # repeat 0 or more times
\/? # optional match for closing '/'
$ # end anchor
Examples Option 2

Regular Expression to only get a specific line

I am attempting to only extract a specific line without any other characters after. For example:
permit ip any any
permit oped any any eq 10.52.5.15
permit top any any (sdfg)
permit sdo any host 10.51.86.17 eq sdg
I would like to match only the first line permit ip any any and not the others. A thing to take note is that the second word ip can be any word.
Meaning, I find only permit (anyword) any any and if there was a character after the second any, do not match.
I tried to do \bpermit.\w+.(?:any.any).([$&+,:;=?##|'<>.^*()%!-\w].+)but that finds the other lines except the permit ip any any. I did attempt to do a reverse lookup, but to no success.
Use the $ end of line anchor after the final "any" and the m multiline regexp flag.
/^permit \w+ any any$/gm
https://regex101.com/r/FfOp5k/2
If you are using Java based regex, you can include the multiline flag in the expression. This syntax is not supported by JavaScript regex.
(?m)^permit \w+ any$
I tried to do \bpermit.\w+.(?:any.any).([$&+,:;=?##|'<>.^*()%!-\w].+) but that finds the other lines except the permit ip any any. I did attempt to do a reverse lookup, but to no success.
Lets take apart your regex to see what your regex says:
\b # starting on a word boundary (space to non space or reverse)
permit # look for the literal characters "permit" in that order
. # followed by any character
\w+ # followed by word characters (letters, numbers, underscores)
. # followed by any character
(?: # followed by a non-capturing group that contains
any # the literal characters 'any'
. # any character
any # the literal characters 'any'
)
. # followed by any character <-- ERROR HERE!
( # followed by a capturing group
[$&+,:;=?##|'<>.^*()%!-\w] # any one of these many characters or word characters
.+ # then any one character one or more times
)
The behavior you describe...
but that finds the other lines except the permit ip any any.
matches what you've specified. Specifically, the regex above requires that there be characters after the 'any any'. Because permit \w+ any any does not have any characters after the any any part, the regex fails at the <-- ERROR HERE! mark in my breakdown above.
If that last part must be captured (using a capturing group) but it may not exist, you can make that entire last part optional using the ? character.
This would look like:
permit \w+ any any(?: (.+))?
for a breakdown of:
permit # the word permit
[ ] # a literal space
\w+ # one or more word characters
[ ] # a literal space
any # the word any
[ ] # another literal space
any # another any; all of this is requred.
(?: # a non-capturing group to start the "optional" part
[ ] # a literal space after the any
(.+) # everything else, including spaces, and capture it in a group
)? # end non-capturing group, but make it optional

regex pattern to match a type of strings

I need to match the below type of strings using a regex pattern in javascript.
E.g. /this/<one or more than one word with hyphen>/<one or more than one word with hyphen>/<one or more than one word with hyphen>/<one or more than one word with hyphen>
So this single pattern should match both these strings:
1. /this/is/single-word
2. /this/is-more-than/single/word-patterns/to-match
Only the slash (/) and the 'this' string in the beginning are consistent and contains only alphabets.
You can use:
\/this\/[a-zA-Z ]+\/[a-zA-Z ]+\/[a-zA-Z ]+
Working Demo
I think you want something like this maybe?
(\/this\/(\w+\s?){1,}\/\w+\/(\w+\s?)+)
break down:
\/ # divder
this # keyword
\/ # divider
( # begin section
\w+ # single valid word character
\s? # possibly followed by a space
) # end section
{1,} # match previous section at least 1 times, more if possible.
\/ # divider
\w+ # single valid word character
\/ # divider
( # begin section
\w+ # single valid word character
\s? # possible space
) # end section
Working example
This might be obvious, however to match each pattern as a separate result, I believe you want to place parenthesis around the whole expression, like so:
(\/[a-zA-Z ]+\/[a-zA-Z ]+\/[a-zA-Z ]+\/[a-zA-Z ]+)
This makes sure that TWO results are returned, not just one big group.
Also, your question did not state that "this" would be static, as the other answers assumed... it says only the slashes are static. This should work for any text combo (no word this required).
Edit - actually looking back at your attempt, I see you used /this/ in your expression, so I assume that's why others did as well.
Demo: http://rubular.com/r/HGYp2qtmAM
Modified question samples:
/this/is/single-word
/this/is-more-than/single/word-patterns/to-match
Modified again The sections may have hyphen (no spaces) and there may be 3 or 4 sections beyond '/this/'
Modified pattern /^\/this(?:\/[a-zA-Z]+(?:-[a-zA-Z]+)*){3,4}$/
^
/this
(?:
/ [a-zA-Z]+
(?: - [a-zA-Z]+ )*
){3,4}
$

Javascript regex for matching twitter-like hashtags

I'd like some help on figuring out the JS regex to use to identify "hashtags", where they should match all of the following:
The usual twitter style hashtags: #foobar
Hashtags with text preceding: abc123#xyz456
Hashtags with space in them, which are denoted as: #[foo bar] (that is, the [] serves as delimiter for the hashtag)
For 1 and 2, I was using something of the following form:
var all_re =/\S*#\S+/gi;
I can't seem to figure out how to extend it to 3. I'm not good at regexps, some help please?
Thanks!
So it has to match either all non-space characters or any characters between (and including) [ and ]:
\S*#(?:\[[^\]]+\]|\S+)
Explanation:
\S* # any number of non-white space characters
# # matches #
(?: # start non-capturing group
\[ # matches [
[^\]]+ # any character but ], one or more
\] # matches ]
| # OR
\S+ # one or more non-white space characters
) # end non-capturing group
Reference: alternation, negated character classes.
How about this?
var all_re =/(\S*#\[[^\]]+\])|(\S*#\S+)/gi;
I had a similar problem, but only want to match when a string starts and ends with the hashtag. So similar problem, hopefully someone else can have use of my solution.
This one matches "#myhashtag" but not "gfd#myhashtag" or "#myhashtag ".
/^#\S+$/
^ #start of regex
\S #Any char that is not a white space
+ #Any number of said char
$ #End of string
Simple as that.

Categories