Match only subregex, part of regex - javascript

Hello I wanted to do autofiller to match to this format "HH:MM".
I wanted to check only against this regex /^(0[1-9]|1[012]):[0-5][0-9]$/ but have no idea how to match regex substring. I've looked at wikipedia and some sites and can't find modificator to check for 'subregex'. Doesn't this option exist? I've finally solved this problem with code below, but this array could certainly be generated programmatically, so there should already be solution I am searching for. Or it doesn't exist and I should write it?
patterns = [ /./, /^[0-9]$/, /^(0?[1-9]|1[012])$/, /^(0[1-9]|1[012]):$/, /^(0[1-9]|1[012]):[0-5]$/, /^(0[1-9]|1[012]):[0-5][0-9]$/]
unless patterns[newTime.length].test(newTime)
newTime = newTime.substring(0, newTime.length - 1)

You could probably accomplish the same thing a bit more efficient.
Combine the regexes into a cascading optional form, then use the match length, substring
and a template to auto complete the time.
Pseudo code (don't know JS too well) and real regex.
# pseudo-code:
# -------------------------
# input = ....;
# template = '00:00';
# rx = ^(?:0(?:[0-9](?::(?:[0-5](?:[0-9])?)?)?)?|1(?:[0-2](?::(?:[0-5](?:[0-9])?)?)?)?)$
# match = regex( input, rx );
# input = input + substr( template, match.length(), -1 );
^
(?:
0
(?:
[0-9]
(?:
:
(?:
[0-5]
(?: [0-9] )?
)?
)?
)?
|
1
(?:
[0-2]
(?:
:
(?:
[0-5]
(?: [0-9] )?
)?
)?
)?
)
$

Related

Javascript regex to match between two patterns, where first pattern is optional

I've tried so many things and tried adapting similar answers... but still lost today to this, if anyone can help I'd be eternally grateful!
I need to use a regex (the JS lexer-library I'm using doesn't allow for anything else) to match:
Any content between $$ and */
Must not include the opening $$
But must include the closing */
The "content" can be any character/digit/whitespace/newline
Given this:
xxx. 123 $$yyy.234 */zzz.567
^^^^^^^^^^
...I need the indicated string to be matched.
As such, this seems to work fine:
(?<=\$\$)(?:[\s\S])*?(?:[\s\S])*?\*\/
(...as seen here)
But there's an additional requirement of:
If there's no $$, then just match to the beginning of the string.
E.g.:
xxx. 123 yyy.234 */zzz.567
^^^^^^^^^^^^^^^^^^^
Yeah, at the limits of my regex knowledge and just can't land it! :-(
Might be worth mentioning the opening $$ symbol isn't quite that solid, it's more like:
\$[\p{L}0-9_]*?\$
When matching against www $$ xxx $$ yyy */ zzz, I'm assuming the result should be $$ yyy */ rather than $$ xxx $$ yyy */. The solution may be more complicated than it needs to be if this isn't a requirement.
(?: ^ | \$\$ ) # Starting at the start of the string or at "$$"
( (?: (?!\$\$). )* # A sequence of characters (.) now of which starting with "$$"
\*/ # Followed by "*/"
) # End capture
Except not quite. That will fail for $$$abc*/. So we fix:
(?: ^ | \$\$(?!\$) ) # Starting at the start of the string or at "$$" (but not "$$$")
( (?: (?!\$\$). )* # A sequence of characters (.) now of which starting with "$$"
\*/ # Followed by "*/"
)
We could also avoid lookaheads.
(?: ^ | \$\$ )
( (?: [^$]+ ( \$[^$]+ )* \$? )?
\*/
)
Regarding the the updated question, the lookahead version can be modified to accommodate \$[\p{L}0-9_]*\$.
(?: ^
| \$ [\p{L}0-9_]* \$ (?! [\p{L}0-9_]* \$ )
)
( (?: (?! \$ [\p{L}0-9_]* \$ ) . )*
\*/
)
I've used line breaks and whitespace for readability. You will need to remove them (since JS's engine doesn't appear to have a flag to cause them to be ignored like some other engines do).
I know this has already been answered and accepted. But here's the shortest way of doing it.
let str = "xxx. $$ 123 $$yyy.234 */zzz.567";
let regex = /\$?\w*\$?([\w \d.-]*\$?[\w \d.-]*\*\/)/gm;
console.log(regex.exec(str)[1]);
Update:
As mentioned in the comments, the above method fails for a $ b */ kind of strings. So, I came up with this. This isn't as good as #ikugami's, but this can definitely be another way.
let str = "$$xxx. $$gjjd*/ fhjgd";
let regex = /(\$?\w*\$?)([\w \d.-]*\$?[\w \d.-]*\*\/)/gm;
result = regex.exec(str).slice(1);
if (result[0].startsWith('$')) {
result = result[1]
} else {
result = result[0] + result[1]
}
console.log(result);

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

JavaScript RegEx - Minimum characters with Wildcard

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

regex to match simple URLs does not work properly

I'm trying to make a simple regex expression to match simple URLs (without URL parameters etc.)
it seems to work but there is still some problem..
This is my regex:
/(https|http|ftp):\/\/((-|[a-z0-9])+\.)+(com|org|net)\/?((-|[a-z0-9]\/?)+(-|[a-z0-9])*\.(css|js))?/ig
In this little list you can see what does not work properly:
HTTP://q-2Ud.a.q-2Ud.com/
https://q-2Ud.q-2Ud.q-2Ud.com
http://www.q-2Ud.q-2Ud.q-2Ud.com
http://www.q-2Ud.q-2Ud.q-2Ud.com/c ------------------------------------> NOT WORK
http://www.q-2Ud.q-2Ud.q-2Ud.com/cs -----------------------------------> NOT WORK
http://www.q-2Ud.q-2Ud.q-2Ud.com/css ----------------------------------> NOT WORK
http://www.q-2Ud.q-2Ud.q-2Ud.com/csss ---------------------------------> NOT WORK
http://www.q-2Ud.q-2Ud.q-2Ud.com/csss/css -----------------------------> NOT WORK
http://www.q-2Ud.q-2Ud.q-2Ud.com/css/yuyuyu/gyygug.css
http://www.q-2Ud.q-2Ud.q-2Ud.com/h/.css -------------------------------> NOT WORK
http://www.q-2Ud.q-2Ud.q-2Ud.com/.css
http://www.q-2Ud.q-2Ud.q-2Ud.com/k.css
http://www.q-2Ud.q-2Ud.q-2Ud.com/kk.css
http://www.q-2Ud.q-2Ud.q-2Ud.com/kkk.css
http://www.q-2Ud.q-2Ud.q-2Ud.com/f-1.css
http://www.q-2Ud.q-2Ud.q-2Ud.com/o/o.css
http://www.q-2Ud.q-2Ud.q-2Ud.com/d-1/d-2/d-3/d-4/f-1.css
http://www.q-2Ud.q-2Ud.q-2Ud.com/q-2Ud/q-2Ud/q-2Ud/q-2Ud/q-2Ud.js
Demo Here
it is matching URLs with .css or .js ending.
Remove \.(css|js) and it should work
/(https|http|ftp):\/\/((-|[a-z0-9])+\.)+(com|org|net)\/?\.?((-|[a-z0-9]\/?)+(-|[a-z0-9])*\/?(\.css|\.js)?)?/ig
This may catch all the ones that you are missing
Just need to arrange the groups a little better while maintaining validity.
This is trimmed to capture just the main 4 parts without delimiters.
edit: If you don't want to match .js or .css without a filename, use this regex ->
(?i)(https|http|ftp)://((?:[a-z0-9-]+\.)+(?:com|org|net))(?:/(?:([a-z0-9-]+(?:/?[a-z0-9-])*(?:\.(css|js))?))?)?
otherwise use this one ->
# /(?i)(https|http|ftp):\/\/((?:[a-z0-9-]+\.)+(?:com|org|net))(?:\/(?:([a-z0-9-]+(?:\/?[a-z0-9-])*)\/?)?(?:\.(css|js))?)?/
(?i)
( https | http | ftp ) # (1)
://
( # (2 start)
(?:
[a-z0-9-]+
\.
)+
(?: com | org | net )
) # (2 end)
(?:
/
(?:
( # (3 start)
[a-z0-9-]+
(?:
/?
[a-z0-9-]
)*
) # (3 end)
/?
)?
(?:
\.
( css | js ) # (4)
)?
)?

Regex to accept only numbers and a specific char

In javascript i have
var regex = /^\d+$/;
which accepts only numbers. How to remake it to accept numbers and the the character '-'
You can use a character class for that:
var regex = /^[\d-]+$/;
However, this will also allow matches like ----. If you only want to allow inputs like 123-456-789 but not -123 or 123- or 123--456, then you can use something like
var regex = /^\d+(?:-\d+)*$/;
Explanation:
^ # Start of string.
\d+ # Match a number.
(?: # Start of a non-capturing group that matches...
- # a hyphen,
\d+ # followed by a number
)* # ...any number of times, including zero.
$ # End of string

Categories