Loading ...
Sorry, an error occurred while loading the content.

47652Re: Preserve case during search & replace?

Expand Messages
  • gumnos (Tim Chase)
    Feb 10, 2004
    • 0 Attachment
      > Basically, I'd like to replace (e.g.) "apple" with "banana"
      > everywhere in a block of text, but if "apple" happens to be
      > capitalized, it should be replaced with "Banana". In other
      > words, I'd like a handy way of doing
      > :s/Apple/Banana/g
      > :s/apple/banana/g
      > (assuming noignorecase) with one command.

      I've toyed with this idea before, even asking the list at one point.
      However, you hit cases (including your own example) where the search-regex
      and the replacement don't line up correctly. eg.


      What's the replacement "FOO"? would it be "BanaNa" or would it be
      "BananA" (is that a "make the 5th letter uppercase", or is it a "make the
      last letter uppercase"). It gets worse, if you use camel-case:


      is likely what you want, but with the below suggestion, you end up with
      something more like


      It really does take some sort of script logic to perform, where the script
      clarifies these peculiar cases. I think there's a simple script (that
      came out when I asked, or perhaps before) that handles the first N
      characters of the replacement text, where N is the length of the matched
      expression. I don't know if its author is around somewhere, or if it's be
      enhanced any.

      It would be of the form (wrapped for email, but should be on all one


      where CaseSubstitute(searchString, replacementString) does something like
      the pseudo-code

      outputString = ""
      for index = 1 to strlen(searchString)
      if isUpper(searchString[i]) outputString =
      outputString . upper(replacementString[i])
      else outputString = outputString .
      append any additional bit of replacementString that
      doesn't have a corresponding letter in the match
      return outputString

      for the isUpper(), you could use
      match(searchString[i], "\\u")

      for upper(), you could use
      substitute(replacementString[i], ".", "\\u&", "")

      for lower(), you could use
      substitute(replacementString[i], ".", "\\l&", "")

      (if OE bunged those replacements by attempting to turn them into UNC
      names, that's back-slash, back-slash, followed by either a "u" or
      lowercase "L", followed by an ampersand)

      You might also prefer to use [:upper:] as a character class rather than
      "\u", which may handle foreign character sets a little more gracefully,
      and the number of backslashes may need to be escaped properly--my guess
      was for only two, but I'm frequently unlucky on my first guess at escaping
      here :)

      Hope this sets you out in a helpful direction,

    • Show all 22 messages in this topic