7

How can I use a single regular expression to replace all words town with village preserving the case of the first letter of each match?

Example input:

Towns are small cities. I live in a town.

Desired output:

Villages are small cities. I live in a village.
cwd
  • 53,018
  • 53
  • 161
  • 198
  • 1
    Which regex engine? So you want Towns = Village? and town = village? Please write the expected output. – FailedDev Nov 04 '11 at 17:52
  • 2
    The right answer is not to try to do it in one regex. Just use two: `s/town/village/g; s/Town/Village/g` – tchrist Nov 04 '11 at 18:36

1 Answers1

4
$_ = "Towns are small cities. I live in a town.\n";

s{ \b (?: (T)|(t) ) own       }
 { $1 ? "Village" : "village" }xge;

print;

# prints: Villages are small cities. I live in a village.
tchrist
  • 78,834
  • 30
  • 123
  • 180
  • +1 For wizard - level regex :). So $1? is *defined* when T is matched? I had no idea this was possible inside a regex. You have to love perl.. – FailedDev Nov 04 '11 at 19:04
  • Nice! But can you explain the syntax a little? Not sure I understand the `\b` and `xge` parts. – cwd Nov 04 '11 at 20:04
  • @cwd This is all described in the *perlre* manpage on your system, or in Chapter 5 of *Programming Perl*: `\b` is a “word boundary”; `/x` is a pattern modifier that allows whitespace and comments in patterns; `/g` is a substitution modifier that makes it do it globally not just once; `/e` is a substitution modifier that says the replacement portion of the substitution is not an interpolated string but rather a code block whose return value is used for the replacement. The pattern and code block are both syntax-checked and compiled at compile time, the very best time for such things to happen. – tchrist Nov 04 '11 at 20:41