5

How can I use a single search / replace to replace all words town with village preserving the case of the first letter in this sentence:

Towns are small cities. I live in a town.

enter image description here

  • 2
    Un-check the ignore-case and do several replacements? – Zoredache Nov 5 '11 at 0:18
9

\b(?:(T)|t)own(s?)\b(?1:\u)village$2

(And uncheck ignore case in the dialog)

  • \b = word boundary
  • (?:) = non-capturing group
  • (?1:\u) = if captured group 1 then convert next character to uppercase
| improve this answer | |
  • This is way smarter than mine, def the way to go – kine Nov 6 '11 at 20:08
  • If I could give you more than one upvote I would. – cwd Nov 9 '11 at 21:43
  • Very cool. Is this regular Perl regexp syntax? – Daniel Beck Nov 11 '11 at 18:11
  • 1
    @DanielBeck No, TextMate uses the oniguruma library. Perl 5 seems to support \u, but not (?1:). – Lri Nov 11 '11 at 19:17
  • Thanks for the link (it requires www. though)! – Daniel Beck Nov 11 '11 at 19:22
2

I'm on my work machine right now, so no TextMate here for me to test on, but i think this might do what you want:

Find:     \b(T)?((?<!T)t)?(?<! )own(s)?\b
Replace:  (?1:Village)(?2:village)$3

(Make sure to untick 'Ignore case' first.)

Explanation:

The 'Find' pattern searches for the letters own preceded by a T or a t, and then captures them to $1 and $2 respectively. The (?<!T) inside the second capture makes sure that you don't get both of them at the same time (like Tt together), as unlikely as that probably is, and the (?<! ) bit means that own can't be preceded by a space — this should prevent it from matching the word own by itself. The \b on either side means that it should only match the whole word (otherwise it will match things like townies and chown). Lastly, the (s)? part captures a final s (if it exists) to $3.

The replace pattern uses conditional insertions to determine what to replace the text by. In pseudo-code the replace string says basically:

if (the first capture [T] exists)  { replace the text by the word Village }
if (the second capture [t] exists) { replace the text by the word village }

(And then it adds $3, which will either be empty or contain an s)

It's ugly, but i think it will probably work for the example you gave anyway.

| improve this answer | |
  • 1
    That deletes \bown\b where the first \b isn't a space. – Lri Nov 6 '11 at 19:24
  • Ah. I guess that is what happens when you don't test things :( – kine Nov 6 '11 at 20:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.