简体   繁体   中英

Regexp: substring not followed by character

Assume a regex that should test true for any string containing the substring hello , followed by any string that does not begin with ! or several of ! .

Some examples for clarity:

var regExp = /someExpression/;

regExp.test("hello"); // → true
regExp.test("hello!"); // → false
regExp.test("hello!!"); // → false
regExp.test("hello!sdkfjhsdfjkh"); // → false
regExp.test("hellos!dkfjhsdfjkh"); // → true
regExp.test("hello-!"); // → true
regExp.test("hello w34~342`!!"); // → true

I have tried several approaches, here's my best:

var regExp = /.*hello[^!].*/;

This will work well on all cases I can come up with but one: "hello" .

In this case, [^!] expects a character.

How can I improve this regex so it tests true for this case as well?

Any kind of help is appreciated.


Edit - bonus points:

The same for hello preceded by a ! , so that hello is accepted, but !hello is not.

You need to use a negative look-ahead rather than a negated character class (that still matches, consumes characters):

var regExp = /.*hello(?!!).*/;

See regex demo

See more details at regular-expressions.info :

Negative lookahead is indispensable if you want to match something not followed by something else . When explaining character classes, this tutorial explained why you cannot use a negated character class to match a q not followed by a u . Negative lookahead provides the solution: q(?!u) . The negative lookahead construct is the pair of parentheses, with the opening parenthesis followed by a question mark and an exclamation point.

EDIT:

Since JS regex engine does not support look-behind, you need to match (^|[^!])hello (where (^|[^!]) matches either start of string or a symbol other than ! ) and then do whatever you need to do with it using JS string methods.

With just those cases, negating /hello!/ works just fine:

var regExp = /hello!/;

!regExp.test("hello"); // → true
!regExp.test("hello!"); // → false
!regExp.test("hello!!"); // → false
!regExp.test("hello-!"); // → true
!regExp.test("hello w34~342`!!"); // → true

See: https://regex101.com/r/xI1mG0/1

使用字符串末尾的简单替换:

/hello([^!]|$)/.test(str);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM