Regex (JavaScript): match feet and/or inches - javascript

I'm trying to match feet and inches but I can't manage to get "and/or" so if first half is correct it validates:
Code: (in javascript)
var pattern = "^(([0-9]{1,}\')?([0-9]{1,}\x22)?)+$";
function testing(input, pattern) {
var regex = new RegExp(pattern, "g");
console.log('Validate '+input+' against ' + pattern);
console.log(regex.test(input));
}
Valid tests should be:
1'
1'2"
2"
2 (assumes inches)
Not valid should be:
* anything else including empty
* 1'1'
But my regex matches the invalid 1'1'.

Remove the + at the end (which allows more than one instance of feet/inches right now) and check for an empty string or illegal entries like 1'2 using a separate negative lookahead assertion. I've also changed the regex so group 1 contains the feet and group 2 contains the inches (if matched):
^(?!$|.*\'[^\x22]+$)(?:([0-9]+)\')?(?:([0-9]+)\x22?)?$
Test it live on regex101.com.
Explanation:
^ # Start of string
(?! # Assert that the following can't match here:
$ # the end of string marker (excluding empty strings from match)
| # or
.*\' # any string that contains a '
[^\x22]+ # if anything follows that doesn't include a "
$ # until the end of the string (excluding invalid input like 1'2)
) # End of lookahead assertion
(?: # Start of non-capturing group:
([0-9]+) # Match an integer, capture it in group 1
\' # Match a ' (mandatory)
)? # Make the entire group optional
(?: # Start of non-capturing group:
([0-9]+) # Match an integer, capture it in group 2
\x22? # Match a " (optional)
)? # Make the entire group optional
$ # End of string

try this
var pattern = "^\d+(\'?(\d+\x22)?|\x22)$";

Not to resurrect the dead, but here was my best shot at detecting fractional feet and inches. It will find:
3'
3'-1" or 3' 1"
3'-1 1/2" or 3' 1 1/2"
3'-1/2", 3' 1/2", 3'-0 1/2", or 3'0 1/2"
1"
1/2"
The only catch is your flavor of regex has to support conditionals.
pattern = "(\d+')?(?:(?(1)(?: |\-))(\d{1,2})?(?:(?(2) )\d+\/\d+)?\x22)?"

Related

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

Regular expression for matching Titles (ex: Book title)

I am using jquery.validate.js plugin to validate a form and I want regex with match Titles(Books or Non-Books or any Title of products) but I failed to match and I wanted a regex which match following,
=> From 'A-Z' , 'a-z', whitespace, as well as tab space , special characters like ' ( ' , ' ) ' , - , _ , and 'coma' , dot , semicolon, ifen ,' : ', and all numbers
I used following regex for above:
/^[a-zA-Z0-9.'\-_\s]$/
/^[\d,\w,\s\;\:\()]$/
/^[^.-_#][A-Za-z0-9_ -.]+$/ - this is showing error when Title starts from upper case 'A'
and I referred following sites
http://regexpal.com/ // in this site i checked the above characters bot it showed error on validate
http://regexlib.com/DisplayPatterns.aspx?AspxAutoDetectCookieSupport=1
http://www.vogella.com/articles/JavaRegularExpressions/article.html
thanks in advance
This regex should match what you want /^[A-Za-z0-9\s\-_,\.;:()]+$/.
Special characters like . & - need escaping with a backslash. You also need a + or * at the end of the square braces to say 'one or more' or 'any number of' respectively.
I think this one you want DEMO
^\w++(?:[.,_:()\s-](?![.\s-])|\w++)*$
Description
^ # Start of string
\w++ # Match one or more alnum characters, possessively
(?: # Match either
[.,_:()\s-] # a "special" character
(?![.\s-]) # aserting that it's really single
| # or
\w++ # one or more alnum characters, possessively
)* # zero or more times
$ # End of string

Regular expression negative match

I can't seem to figure out how to compose a regular expression (used in Javascript) that does the following:
Match all strings where the characters after the 4th character do not contain "GP".
Some example strings:
EDAR - match!
EDARGP - no match
EDARDTGPRI - no match
ECMRNL - match
I'd love some help here...
Use zero-width assertions:
if (subject.match(/^.{4}(?!.*GP)/)) {
// Successful match
}
Explanation:
"
^ # Assert position at the beginning of the string
. # Match any single character that is not a line break character
{4} # Exactly 4 times
(?! # Assert that it is impossible to match the regex below starting at this position (negative lookahead)
. # Match any single character that is not a line break character
* # Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
GP # Match the characters “GP” literally
)
"
You can use what's called a negative lookahead assertion here. It looks into the string ahead of the location and matches only if the pattern contained is /not/ found. Here is an example regular expression:
/^.{4}(?!.*GP)/
This matches only if, after the first four characters, the string GP is not found.
could do something like this:
var str = "EDARDTGPRI";
var test = !(/GP/.test(str.substr(4)));
test will return true for matches and false for non.

/PM regex syntax for sending message in chat-room

I am working on a AJAX/PHP chatroom and am currently stuck on the regex to detect if a user has send a PM & then work out who it is too and what the message is.
If the user types something like
/pm PezCuckow Hi There you so awesome!
I would like to first test if my string matched that pattern then get 'PezCuckow' and 'Hi There you so awesome!' as strings to post to the PHP.
I have done some research on regex but really have no idea where to start with this one!
Can you help?
==Thanks to everyones help this is now solved!==
var reg = /^\/pm\s+(\w+)\s+(.*)$/i;
var to = "";
if(message.match(reg)) {
m = message.match(reg);
to = m[1];
message = m[2];
}
This regex parses a message:
^(?:\s*/(\w+)\s*(\w*)\s*)?((?:.|[\r\n])*)$
Explanation:
^ # start-of-string
(?: # start of non-capturing group
\s*/ # a "/", preceding whitespace allowed
(\w+) # match group 1: any word character, at least once (e.g. option)
\s+ # delimiting white space
(\w*) # match group 2: any word character (e.g. target user)
\s+ # delimiting white space
)? # make the whole thing optional
( # match group 3:
(?: # start of non-capturing group, either
. # any character (does not include newlines)
| # or
[\r\n] # newline charaters
)* # repeat as often as possible
) # end match group 3
In your case ("/pm PezCuckow Hi There you so awesome!"):
group 1: "pm"
group 2: "PezCuckow"
group 3: "Hi There you so awesome!"
in a more general case ("Hi There you so awesome!")
group 1: ""
group 2: ""
group 3: "Hi There you so awesome!"
Note that the forward slash needs to be escaped in JavaScript regex literals:
/foo\/bar/
but not in regex patterns in general.
Hows about this:
var reg = /^\/pm\s+(\w+)\s+(.*)$/i,
m = '/pm PezCuckow Hi There you so awesome!'.match(reg);
m[0]; // "PezCuckow"
m[1]; // "Hi There you so awesome!"
That matches "/pm" followed by whitespace " " (liberally accepting extra spaces), followed by the username \w+, followed by whitespace " " agin, then finally the message .* (which is basically everything to the end of the line).
Assuming that only word characters (no spaces, etc) are valid in the name field, this'll do what you want:
var re = /(\/\w+) (\w+) (.+)/;

Categories