Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

regex

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
  • Matches fez
  • Matches day
  • Doesnt match fyyyz as it ends in yz
  • Doesnt match fyyzy as it ends in zy

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

[yz\b]

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

like image 405
Samridhi Dubey Avatar asked Sep 12 '25 02:09

Samridhi Dubey


2 Answers

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.
like image 61
Wiktor Stribiżew Avatar answered Sep 13 '25 15:09

Wiktor Stribiżew


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

like image 30
anubhava Avatar answered Sep 13 '25 15:09

anubhava