0

I would appreciate if you could please correct my understanding of the following code in perl:

my $sgn            = "(b|f|h|m)";  
$sometext =~ s/([^$sgn])d$/$1X/g; 

What I think is happening here is that it tries to match a character which is not in the $sgn. then if this character happens to be the one next to the last letter and if the last character is d it replaces the two last character by X? For example book will not change but bad will change to bX. Put it simply if the last two letters are a combination any of the letters not in $sgn and d it will replace them by X. Thanks in advance for your comments. Bid

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Bid
  • 39
  • 5
  • Does this answer your question? [Reference - What does this regex mean?](https://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean) – Wiktor Stribiżew Jul 01 '22 at 19:02
  • You can test your regex [at regex101](https://regex101.com/r/pxBw5l/1) (explanation on the right side). Be aware that `[`...`]` describes a charcter-set. It does not make much sense to put `(b|f|h|m)` into a [character class](https://www.regular-expressions.info/charclass.html) - `[^(b|f|h|m)]` is equivalent to `[^bfhm)(|]` – bobble bubble Jul 01 '22 at 19:16
  • Thanks for your comment, I did try it there. I just wanted to verify if my understanding is correct and I need to convert it Dart, so before that I have to make sure the logic of the code is what explained – Bid Jul 01 '22 at 19:26
  • 1
    That is most likely an error, is what @bobblebubble explains. Assuming that they mean either-of those four (by `|`s in `$sgn`), then you have `s/([^bfhm]d$/$1X/` (that `/g` modifier makes no sense since the pattern is anchored to the end of string so I removed it). Then the logic is: if a character which is neither of those four precedes a `d` and which is the last char in the string, then keep that character but replace `d` by `X`. So `bad` becomes `baX`. (It keeps that character because it captures it with `()` and puts it back with that `$1` in replacement.) – zdim Jul 01 '22 at 19:50
  • Note that `$` does not mean the same thing in JS/Dart regex patterns and Perl regex patterns. – ikegami Jul 01 '22 at 19:59

1 Answers1

1

It replaces the last or second last character of $sometext depending on the last preceding and following character.

  • If the last character is d, replace the d with an X if the preceding character isn't one of b, f, h, m, |, (, or ).

    ...ad       ⇒       ...aX
    ...cd       ⇒       ...cX
    ...!d       ⇒       ...!X
    
    ...bd       ⇒       ...bd
    ...fd       ⇒       ...fd
    ...(d       ⇒       ...(d
    ...|d       ⇒       ...|d
    ...)d       ⇒       ...)d
    
  • If the last two characters are d␊, replace the d with an X if the preceding character isn't one of b, f, h, m, |, (, or ).

    ...ad␊      ⇒       ...aX␊
    ...cd␊      ⇒       ...cX␊
    ...!d␊      ⇒       ...!X␊
    
    ...bd␊      ⇒       ...bd␊
    ...fd␊      ⇒       ...fd␊
    ...(d␊      ⇒       ...(d␊
    ...|d␊      ⇒       ...|d␊
    ...)d␊      ⇒       ...)d␊
    
  • No change if the string ends with anything else.

    ...ae       ⇒       ...ae
    ...ce       ⇒       ...ce
    
    ...ae␊      ⇒       ...ae␊
    ...ce␊      ⇒       ...ce␊
    

Note that the author obviously meant to use

my $sgn = "(b|f|h|m)";  

instead of

my $sgn = "bfhm";

Note that the author might have meant to use

d\z

instead of

d$
ikegami
  • 367,544
  • 15
  • 269
  • 518