2

The thing I have to do, is to make a regular expression for "penguins"

Rules go like this:

  • A penguin is denoted by the word Peng if it looks to the right, and with Gnep if it looks to the left.
  • In each row, only penguins occur (no polar bears, e.g.).

If a penguin is hided by the subsequent penguin, a suffix of its word is removed.

Examples:

  • Pen describes a right-looking penguin who is partly hidden.
  • Gn describes a left-looking penguin who is severely hidden.

We are only interested in penguins of which at least one third is visible. All others are ignored. This means that the remaining portion must at least contain two characters.

A row of penguins is written by concatenating their words. Examples with two penguins in a row:

  • PengPeng - both penguins are fully visible.
  • GnePeng - the right penguin (Peng) hides the left penguin (Gne).

The rightmost penguin is the last in the row and therefore is fully visible.

Each row consists of at least one penguin.

The expression I wrote is:

((P|G)(([eng]|[nep]){1,4}))*((Peng|Gnep)+)

I tested the test words:

Peng       works    
Gnep       works
Pen        doesnt 
PengPeng     works
PenGnep      works
PPeng       works - shouldnt
Pooh       doesnt
PengPe     works - shouldnt

What do I need to change? Testing done via Regexr.com

Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397
  • 1
    You confuse character classes with groups. Try `^(?:Pe(?:ng?)?|Gn(?:ep?)?)*(?:Peng|Gnep)$`, see [the regex demo](https://regex101.com/r/3nu1ds/1). – Wiktor Stribiżew Oct 25 '20 at 17:51
  • @WiktorStribiżew That worked. Could you explain what exactly was I missing and confusing? – David Petriashvili Oct 25 '20 at 18:02
  • @WiktorStribiżew I'm more interested in ?: expression. What does this mean. – David Petriashvili Oct 25 '20 at 18:04
  • 1
    1) You wanted to match optional two chars of each alternative in the correct order, thus, you can't use character class like `[nep]{1,3}`, it should be build using groups and optional constructs, `(?:n(ep?)?)?`. 2) `(?:...)` is a [non-capturing group](https://stackoverflow.com/questions/3512471/what-is-a-non-capturing-group-in-regular-expressions). – Wiktor Stribiżew Oct 25 '20 at 18:06
  • Massive thanks, Wiktor! Cheers! – David Petriashvili Oct 25 '20 at 18:07

1 Answers1

2

You can use

^(?:Pe(?:ng?)?|Gn(?:ep?)?)*(?:Peng|Gnep)$

See the regex demo

Details

  • ^ - start of string
  • (?:Pe(?:ng?)?|Gn(?:ep?)?)* - zero or more occurrences of
    • Pe(?:ng?)? - Pe followed with an optional occurrence of n followed with an optional g
    • | - or
    • Gn(?:ep?)? - Gn followed with an optional occurrence of e followed with an optional p
  • (?:Peng|Gnep) - either Peng or Gnep strings
  • $ - end of string.
Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397