Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
145 views
in Technique[技术] by (71.8m points)

How to match, but not capture, part of a regex?

I have a list of strings. Some of them are of the form 123-...456. The variable portion "..." may be:

  • the string "apple" followed by a hyphen, e.g. 123-apple-456
  • the string "banana" followed by a hyphen, e.g. 123-banana-456
  • a blank string, e.g. 123-456 (note there's only one hyphen)

Any word other than "apple" or "banana" is invalid.

For these three cases, I would like to match "apple", "banana", and "", respectively. Note that I never want capture the hyphen, but I always want to match it. If the string is not of the form 123-...456 as described above, then there is no match at all.

How do I write a regular expression to do this? Assume I have a flavor that allows lookahead, lookbehind, lookaround, and non-capturing groups.


The key observation here is that when you have either "apple" or "banana", you must also have the trailing hyphen, but you don't want to match it. And when you're matching the blank string, you must not have the trailing hyphen. A regex that encapsulates this assertion will be the right one, I think.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The only way not to capture something is using look-around assertions:

(?<=123-)((apple|banana)(?=-456)|(?=456))

Because even with non-capturing groups (?:…) the whole regular expression captures their matched contents. But this regular expression matches only apple or banana if it’s preceded by 123- and followed by -456, or it matches the empty string if it’s preceded by 123- and followed by 456.

Lookaround Name What it Does
(?=foo) Lookahead Asserts that what immediately FOLLOWS the current position in the string is foo
(?<=foo) Lookbehind Asserts that what immediately PRECEDES the current position in the string is foo
(?!foo) Negative Lookahead Asserts that what immediately FOLLOWS the current position in the string is NOT foo
(?<!foo) Negative Lookbehind Asserts that what immediately PRECEDES the current position in the string is NOT foo

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...