Adrian B.
Adrian B.

Reputation: 1570

Regex for matching substring, but not containing word

I'd like to be able to use a regular expression to match a given string, but not a specific longer word which contains it. Here's an example to better explain:

Given the text:

String bellsringing = "The bells are ringing is a String";

I want to be able to find all occurences of "ring", that are not part of the word String, not limited to word (can appear inside one). So the answer would be only "bells(ring)ing" and "(ring)ing".

I am aware that a program can be used for such a task, but I have come accross the need to find specific strings in large libraries and if the sought string is a substring of a common keyword / literal, I have lots of digging to do and would benefit from the IDE's search using regex function :)

Thanks for any input on this.

Upvotes: 0

Views: 3609

Answers (3)

OnlineCop
OnlineCop

Reputation: 4069

Building off of @Fede's answer, use a negative look-ahead:

\b(?!String)\w*ring\w*\b

This will start at a word boundary, ensure that it doesn't find String, and then match ring where it can.

Working example

Upvotes: 2

Federico Piazza
Federico Piazza

Reputation: 31035

PCRE (Perl Compatible Regular Expression)

If you are using PCRE regex then you could use a regex like this:

String(*SKIP)(*FAIL)|ring

Working demo

enter image description here

The idea of this regex is to fail string pattern so it will skip it but will keep ring. Btw, if you want to grab the complete word you could use this regex:

String(*SKIP)(*FAIL)|(\w*ring\w*)

The match information is:

MATCH 1
1.  [14-21] `ringing`
MATCH 2
1.  [64-71] `ringing`

Other engines

On the other hand, if you are not using PCRE you could leverage the discard pattern that's a really nice regex trick by doing this:

String|(\w*ring\w*)

Working demo

enter image description here

In this case what you do is to match what you don't want on the left side of the pattern while you keep what you want on the rightest part using a group. The discard pattern follows this rule:

discard patt1 | discard patt2 | ... | discard pattN | (KEEP THIS PATTERN)

Then you have to access to the regex group \1 or $1 to grab the saved string. For this case is:

MATCH 1
1.  [14-21] `ringing`
MATCH 2
1.  [64-71] `ringing`

Debuggex does a good job displaying graphically this technique:

Regular expression visualization

Upvotes: 3

vks
vks

Reputation: 67988

String|\b(\w*?ring\w*)\b

Try this.Grab the capture.See demo.Apply i flag.

http://regex101.com/r/tF5fT5/39

Upvotes: 0

Related Questions