views:

76

answers:

6

I apologize, but I'm terrible at understanding regular expressions. Could anyone help me with a simple problem?

I need one regex to match everything before and one to match everything after a certain character, like a colon.

 foo:bar

Something to match 'foo' and something to match 'bar'.

+2  A: 

You don't need regular expressions here.

var middle = str.indexOf(':');
var key = str.substr(0, middle);
var value = str.substr(middle + 1);

If you do want to use regular expressions, you can do it like this:

var matches = /([^:]+):(.+)/.exec(str);

var key = matches[1];
var value = matches[2];
SLaks
I agree. I think he is the middle of learning them, though.
ZJR
+1 for meeting the criteria of everything before and everything after the colon :-)
Andy E
+1  A: 

These two should do it:

'foo:bar'.match(/(.*):/)
'foo:bar'.match(/:(.*)/)

Will there be more than one ":" in the string? If so, you'd probably prefer this one:

'foo:bar'.match(/(.*?):/)
ZJR
+7  A: 

Don't use regexes for that. Use split.

mcandre
`split` will fail if the value has a `:`.
SLaks
@SLake No it won't.
mcandre
It won't return the entire value.
SLaks
@SLaks you have to provide also the `":"` argument to `split` :)
mykhal
@mcandre: What SLaks is trying to say is, if the part of the string after `:` also contains a colon the result will contain 3 substrings. This doesn't fit the question's criteria of, *"I need one regex to match everything before and one to match **everything after a certain character**, like a colon"*. However, it's likely that the OP specified that requirement with a little naivety and `split` is good enough for him :-)
Andy E
+2  A: 

In regex you are able to define groups (by parentheses).

"foo:bar".match(/(.*?):(.*)/) // -> ["foo:bar", "foo", "bar"]
//                               whole regexp, 1st group, 2nd group

.*? in first group means non-greedy version of .*, which prevents eating all of the string by it (matching as less as possible .'s)

(which really does not matter in this case, but matters when you'll be matching e.g. "foo:bar:spam")

mykhal
+1  A: 

If you want to use a regexp instead of str.split, you can use:

var str="foo:bar";
var pattern=/([^:]+):([^:]+)/gi;
var arr=pattern.exec(str);
arr.shift();

Now arr will be an array of two elements: ['foo', 'bar'].

saverio
+1  A: 

You want look-ahead, and look-behind. Which match stuff followed by, or preceded by a certain character, without including that character in the match.

For look-ahead, you'd have something like .*(?=:) , which means any character, 0 or more times, followed by a colon, but don't include the colon in the match,

For look-behind, you have .*(?<=:) , which means any character 0 or more times, preceded by a colon, but don't include the colon in the match. The trick here is that the look-behind expression comes AFTER the rest, which can seem counter intuitive, because you're looking for a colon that comes before, but it's because any regex really returns a position, and you want the colon to come right before that position.

LoveMeSomeCode