Samridhi Dubey
Samridhi Dubey

Reputation: 97

Regular Expression to match word ending with either y or z, but noth both together

I am looking for a regular expression which matches words ending with y or z, but not both together.

Here are some test cases:

fez day fyyyz fyyzy

I was trying this regular expression, but it isn't working.

[yz\b]

Regex Tool I am using is - http://www.regexr.com/

Upvotes: 4

Views: 2763

Answers (4)

vks
vks

Reputation: 67968

\b\w*[yz](?<!(?:yz|zy))\b

Try this. Lookbehind will make sure you don't have yz or zy as end. See demo.

https://regex101.com/r/Gtplnq/1

Upvotes: 2

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626929

You may use

\b\w*[yz]\b(?<!yz)

or - if the word can't end with yz OR zy:

\b\w*[yz]\b(?<!yz|zy)

It matches any word ending with y or z, but not yyz (or with (?<!yz|zy), not those ending with yz or zy).

See the regex demo

Note that \b inside square brackets is not a word boundary, but a backspace matching escape sequence.

Pattern details

  • \b - leading word boundary
  • \w* - 0+ word chars (letters, digits or _, it can be adjusted to match just letters with [^\W\d_]*)
  • [yz] - a y or z
  • \b - trailing word boundary
  • (?<!yz) - a negative lookbehind that fails the match if there is a yz char sequence immediately before the current location.

EDIT: Now, that all Perl, Python and Java tags are removed, it might also attract the attention of people who would like to use the regex in VBA, C++ std::regex (default flavor of which is ECMAScript5), or JavaScript whose regex engines (ECMA-5 standard) does not support lookbehinds, but do support lookaheads.

You may use

/\b(?!\w*(?:yz|zy)\b)\w*[yz]\b/

See the regex demo.

Details:

  • \b - leading word boundary
  • (?!\w*(?:yz|zy)\b) - a negative lookahead that is executed right after finding a word boundary, and it will fail the match if after 0+ word chars, there is either yz or zy followed with the trailing word boundary
  • \w* - consuming the 0+ word chars
  • [yz] - y or z
  • \b - trailing word boundary.

Upvotes: 4

stevieb
stevieb

Reputation: 9296

Another way, without lookbehinds:

/\w*(?:[^y]z|[^z]y)\b/

Example

Upvotes: 1

anubhava
anubhava

Reputation: 785256

If your word are not 1 in length then use:

/\b\w*(?:[^z]y|[^y]z)\b/

RegEx Demo 1

If you can have 1 character word as well then you can use this negative lookahead regex:

/\b(?!\w*(?:yz|zy)\b)\w*[yz]\b/

RegEx Demo 2

Upvotes: 2

Related Questions