user857521
user857521

Reputation:

Regex non-greedy match

If I have the following simplified string:

        string331-itemR-icon253,string131-itemA-icon453,
string12131-itemB-icon4535,string22-itemC-icon443

How do I get the following only using only regex?

string12131-itemB-icon4535,

All numbers are unknown. The only known parts are itemA, itemB, itemC, string and icon

I've tried string.+?itemB.+?, but it also picks up from the first occurrence of string rather than the one adjacent to itemB

I've also tried using [^icon] preceding the itemB in various positions but couldn't get it to work.

Upvotes: 1

Views: 1125

Answers (4)

xan
xan

Reputation: 7731

The given solutions that use a restricted set of characters instead of a wildcard are simplest, but to get more at the general question: You got the non-greedy quantifier part right, but being non-greedy doesn't prevent the matcher from taking as many characters as it needs to find a match. You might be looking for the atomic group operator, (?>group). Once the group matches something, it will be treated atomically if the matcher needs to backtrack.

(?>string.+?item)B.+?,

In your example, the group matches string331-item, but the B doesn't match R so the whole group is tossed and the search moves to the next string.

Upvotes: 2

deaks
deaks

Reputation: 252

You don't mention the commas separating items as a known part but use it in the example regex so I assume it can be used in a solution. Try excluding the comma as a character set instead of matching against ".".

Upvotes: 0

lahsrah
lahsrah

Reputation: 9183

Try this regex

 string\d+-itemB-icon\d+,

Upvotes: 2

dtb
dtb

Reputation: 217411

Try this:

string[^,]+itemB[^,]+,

Upvotes: 3

Related Questions