Liu Kang
Liu Kang

Reputation: 1389

Non-capturing group is not greedy?

I want to remove everything after the first

Sample:

Yes – No – No – No
Yes – No – No & No – No
Yes Yes – No & No – No
Yes – No – No & No 
Yes – No
Yes – No – No

Regex I am using:

/(.+) (?:– .+)/

Match:

`Yes – No – No`
`Yes – No – No & No`
`Yes Yes – No & No`
`Yes – No`
`Yes`
`Yes – No`

It seems like the non-capturing group is lazy rather than greedy?

My desired result is:

`Yes`
`Yes`
`Yes Yes`
`Yes`
`Yes`
`Yes`

Upvotes: 6

Views: 3286

Answers (4)

vks
vks

Reputation: 67968

(.+?) (?:– .+)

This will give the desired result.Your regex (.+) (?:– .+) is incorrect as .+ will try to match as many characters as possible before stopping, so it will stop at the last -. Instead, use .+? to make it lazy.

http://regex101.com/r/hS3dT7/3

Upvotes: 4

nhahtdh
nhahtdh

Reputation: 56809

Another simple solution, although it is not recommended in production code, since it may incur performance hit if the string contains a long streak of consecutive spaces but no dash. (The same problem also occurs when you write [ \t]+$ to remove trailing spaces and tabs).

Search with this regex (the separator / is added for clarity):

/ *–.*/

And replace with empty string.

DEMO

The idea is very simple. We just search for the first dash, which may be preceded by spaces, and remove them along with everything that comes after them.

Upvotes: 0

lc.
lc.

Reputation: 116458

Actually it's the first (capturing) group being greedy that is the problem. The regular expression engine will try to fill the leftmost part of the pattern first. Try making the first group lazy:

/(.+?) (?:– .+)/

On the other hand, you don't really need a group for the second bit anyway, and can just capture up to the first - (with optional whitespace before it) and be done with it:

/^(.*?)\s*-/

Or if you don't care about whitespace or want to trim afterward, it's simply:

/^([^-]*)/

Upvotes: 1

Avinash Raj
Avinash Raj

Reputation: 174696

Use the below regex and remove the matched strings.

^[^–]*\K\s+–.*

DEMO

Upvotes: 0

Related Questions