1252748
1252748

Reputation: 15379

match a string not after another string

This

var re = /[^<a]b/; 
var str = "<a>b";

console.log(str.match(re)[0]);

matches >b.

However, I don't understand why this pattern /[^<a>]b/ doesn't match anything. I want to capture only the "b".

Upvotes: 0

Views: 111

Answers (4)

Sujith PS
Sujith PS

Reputation: 4864

Your code :

var re = /[^<a>]b/; 
var str = "<a>b";
console.log(str.match(re));

Why [^<a>]b is not matching with anything ?

The meaning of [^<a>]b is any character except < or a or > then b .

Hear b is followed by > , so it will not match .

If you want to match b , then you need to give like this :

var re = /(?:[\<a\>])(b)/; 
var str = "<a>b";    
console.log(str.match(re)[1]);

DEMO And EXPLANATION

Upvotes: -1

omid.n
omid.n

Reputation: 491

you could write a pattern to match anchor tag and then replace it with empty string

var str = "<a>b</a>";    
str = str.replace(/((<a[\w\s=\[\]\'\"\-]*>)|</a>)/gi,'')

this will replace the following strings with 'b'

<a>b</a>
<a class='link-l3'>b</a>

to better get familiar with regEx patterns you may find this website very useful regExPal

Upvotes: 0

Joeytje50
Joeytje50

Reputation: 19122

What you're using here is a match for a b preceded by any character that is not listed in the group. The syntax [^a-z+-] where the a-z+- is a range of characters (in this case, the range of the lowercase Latin letters, a plus sign and a minus sign). So, what your regex pattern matches is any b preceded by a character that is NOT < or a. Since > doesn't fall in that range, it matches it.

The range selector basically works the same as a list of characters that are seperated by OR pipes: [abcd] matches the same as (a|b|c|d). Range selectors just have an extra functionality of also matching that same string via [a-d], using a dash in between character ranges. Putting a ^ at the start of a range automatically turns this positive range selector into a negative one, so it will match anything BUT the characters in that range.

What you are looking for is a negative lookahead. Those can exclude something from matching longer strings. Those work in this format: (?!do not match) where do not match uses the normal regex syntax. In this case, you want to test if the preceding string does not match <a>, so just use:

(?!<a>)(.{3}|^.{0,2})b

That will match the b when it is either preceded by three characters that are not <a>, or by fewer characters that are at the start of the line.

PS: what you are probably looking for is the "negative lookbehind", which sadly isn't available in JavaScript regular expressions. The way that would work is (?<!<a>)b in other languages. Because JavaScript doesn't have negative lookbehinds, you'll have to use this alternative regex.

Upvotes: 2

Kevin Ji
Kevin Ji

Reputation: 10499

The reason why /[^<a>]b/ doesn't do anything is that you are ignoring <, a, and > as individual characters, so rewriting it as /[^><a]b/ would do the same thing. I doubt this is what you want, though. Try the following:

var re = /<a>(b)/; 
var str = "<a>b";

console.log(str.match(re)[1]);

This regex looks for a string that looks like <a>b first, but it captures the b with the parentheses. To access the b, simply use [1] when you call .match instead of [0], which would return the entire string (<a>b).

Upvotes: 2

Related Questions