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+) (.+)/;
Related
Need to capitalize the first letter of each word in a sentence, my regex expression however is also capitalizing the 'm' in I'm.
The full expression is this:
/(?:^\w|[A-Z]|\b\w)/g
The problem here (I think) is that \b\w will grab the first letter after a word boundary. I'm assuming that single quotes denote a word boundary therefore also capitalizing the m of I'm into I'M.
Can anyone help me change the expression to exclude the 'm' after the single quotes?
Thanks in advance.
Finding a real word break in the middle of language might be a bit more
complicated than using regex word boundary's.
( \s* [\W_]* ) # (1), Not letters/numbers,
( [^\W_] ) # (2), Followed by letter/number
( # (3 start)
(?: # -----------
\w # Letter/number or _
| # or,
[[:punct:]_-] # Punctuation
(?= [\w[:punct:]-] ) # if followed by punctuation/letter/number or '-'
| #or,
[?.!] # (Add) Special word ending punctuation
)* # ----------- 0 to many times
) # (3 end)
var str = 'This "is the ,input _str,ng, the End ';
console.log(str);
console.log(str.replace(/(\s*[\W_]*)([^\W_])((?:\w|[[:punct:]_-](?=[\w[:punct:]-])|[?.!])*)/g, function( match, p1,p2,p3) {return p1 + p2.toUpperCase() + p3;}));
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)?"
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
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.
I'm writing a rudimentary lexer using regular expressions in JavaScript and I have two regular expressions (one for single quoted strings and one for double quoted strings) which I wish to combine into one. These are my two regular expressions (I added the ^ and $ characters for testing purposes):
var singleQuotedString = /^'(?:[^'\\]|\\'|\\\\|\\\/|\\b|\\f|\\n|\\r|\\t|\\u[0-9A-F]{4})*'$/gi;
var doubleQuotedString = /^"(?:[^"\\]|\\"|\\\\|\\\/|\\b|\\f|\\n|\\r|\\t|\\u[0-9A-F]{4})*"$/gi;
Now I tried to combine them into a single regular expression as follows:
var string = /^(["'])(?:[^\1\\]|\\\1|\\\\|\\\/|\\b|\\f|\\n|\\r|\\t|\\u[0-9A-F]{4})*\1$/gi;
However when I test the input "Hello"World!" it returns true instead of false:
alert(string.test('"Hello"World!"')); //should return false as a double quoted string must escape double quote characters
I figured that the problem is in [^\1\\] which should match any character besides matching group \1 (which is either a single or a double quote - the delimiter of the string) and \\ (which is the backslash character).
The regular expression correctly filters out backslashes and matches the delimiters, but it doesn't filter out the delimiter within the string. Any help will be greatly appreciated. Note that I referred to Crockford's railroad diagrams to write the regular expressions.
You can't refer to a matched group inside a character class: (['"])[^\1\\]. Try something like this instead:
(['"])((?!\1|\\).|\\[bnfrt]|\\u[a-fA-F\d]{4}|\\\1)*\1
(you'll need to add some more escapes, but you get my drift...)
A quick explanation:
(['"]) # match a single or double quote and store it in group 1
( # start group 2
(?!\1|\\). # if group 1 or a backslash isn't ahead, match any non-line break char
| # OR
\\[bnfrt] # match an escape sequence
| # OR
\\u[a-fA-F\d]{4} # match a Unicode escape
| # OR
\\\1 # match an escaped quote
)* # close group 2 and repeat it zero or more times
\1 # match whatever group 1 matched
This should work too (raw regex).
If speed is a factor, this is the 'unrolled' method, said to be the fastest for this kind of thing.
(['"])(?:(?!\\|\1).)*(?:\\(?:[\/bfnrt]|u[0-9A-F]{4}|\1)(?:(?!\\|\1).)*)*/1
Expanded
(['"]) # Capture a quote
(?:
(?!\\|\1). # As many non-escape and non-quote chars as possible
)*
(?:
\\ # escape plus,
(?:
[\/bfnrt] # /,b,f,n,r,t or u[a-9A-f]{4} or captured quote
| u[0-9A-F]{4}
| \1
)
(?:
(?!\\|\1). # As many non-escape and non-quote chars as possible
)*
)*
/1 # Captured quote
Well, you can always just create a larger regex by just using the alternation operator on the smaller regexes
/(?:single-quoted-regex)|(?:double-quoted-regex)/
Or explicitly:
var string = /(?:^'(?:[^'\\]|\\'|\\\\|\\\/|\\b|\\f|\\n|\\r|\\t|\\u[0-9A-F]{4})*'$)|(?:^"(?:[^"\\]|\\"|\\\\|\\\/|\\b|\\f|\\n|\\r|\\t|\\u[0-9A-F]{4})*"$)/gi;
Finally, if you want to avoid the code duplication, you can build up this regex dynamically, using the new Regex constructor.
var quoted_string = function(delimiter){
return ('^' + delimiter + '(?:[^' + delimiter + '\\]|\\' + delimiter + '|\\\\|\\\/|\\b|\\f|\\n|\\r|\\t|\\u[0-9A-F]{4})*' + delimiter + '$').replace(/\\/g, '\\\\');
//in the general case you could consider using a regex excaping function to avoid backslash hell.
};
var string = new RegExp( '(?:' + quoted_string("'") + ')|(?:' + quoted_string('"') + ')' , 'gi' );