Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Replace [In selection] if selection=column

2. Help
2009-06-29
2012-11-13
  • The Beerslayer
    The Beerslayer
    2009-06-29

    Version: 5.4.3 (also true in 5.3.1)

    I would like to replace text within a selection (but not outside of that selection).  Unfortunately, the selection is made in Column mode (hold Alt key while selecting), and the box "In selection" is disabled in the Replace dialog when the selection is made in Column mode.

    Is this by design, by oversight, or by bug?  If by design, I urge the developer to reconsider.  If by oversight or by bug, please fix!

    Thanks for an otherwise great program!

     
    • Fool4UAnyway
      Fool4UAnyway
      2009-06-29

      Use Ctrl+R to get the Text FX advanced Find/Replace dialog.

      You can enter column numbers here.
      Combined with a normal selection you could achieve what you want.

      Be aware, though, because any replacement may affect consecutive replacements. If you would have a line

      12345 12345 12345

      and want to replace only in the first 11 columns (first two numbers 12345) by a single character @ for example, also the third number will be replaced, because at the time the search engine gets there, there are only 4 characters before it, instead of the previous 12.

      Intended result:
      @ @ 12345

      Effective result:
      @ @ @

      Search the forum more for similar messages and threads.

       
    • The Beerslayer
      The Beerslayer
      2009-06-29

      Thanks for the reply.  I did not know about the Ctrl-R functionality.

      This almost, but not quite works for me.  What I'm trying to do is to convert a space-delimited text file into a comma-separated (.csv) file.  The data is in columns, separated by spaces, but the content itself may also contain spaces so I can't do a simple search-and-replace.  So I use Column mode to select the columns of spaces that I do want to replace (with three characters: ",").  So what I start with in the selection is:

      xyz 123 abc def
      xyz 123 abc def
      ...

      ("abc def" is one column - there are three columns of data here)

      Desired result is:
      xyz","123","abc def
      ...

      I use column select to select everything from z through a inclusive in all the columns, then attempt to search and replace as you described.  But it only replaces the first selected space (between z and 1), not the second (between 3 and a).

       
      • Fool4UAnyway
        Fool4UAnyway
        2009-06-30

        What I said about consecutive replacement influence before in case of _deleting_ characters, is also true when you _add_ them.

        Here's what happens.

        xyz 123 abc def
        xyz 123 abc def

        You select the column range:
        >>z 123 a<<

        The Ctrl+R Replace dialog recognizes this selection.

        Now you replace each single space character by three other characters.

        The result of the first replacement is this:
        >>z","123 a<<

        Oh no, that is what you _think_ it would be.

        The replace function _still_ considers the range of the absolute columns you entered (or confirmed by leaving them unchanged) before.

        This, then, is your "new selection":
        >>z","123<<

        One space character was removed, three other characters inserted.
        The result is that you lose two characters at the end of your original selection.

        Now, there is no more space character in your column range selection.

        So you should take into account the (extra) characters that are _added_ by the replacements.

        Perhaps a better way to perform you changes would be using regular expressions, or simply columnar selection or the column editor.

        All would do if all your space characters are at absolute positions.
        Just select the rectangular column of the space characters, press Alt+C and enter ",".

        Regular expressions will perhaps also do if the space characters are at different positions.
        You could simply check for occurrences of
        ([^ ]+)_
        (_ represents a space character) or
        ([^ ]+ [^ ]+ )
        and replace them by \1",".

        Do a forum search to find out more about those magic replacements.

         
    • cchris
      cchris
      2009-06-30

      Uncheck the "1 per line" checkbox in the Ctrl+R, aka TextFX -> TextFX Quick -> Find/Replace, dialog. I'm not sure if playing with "Recursive repl" would help here.

      CChris

       
    • The Beerslayer
      The Beerslayer
      2009-07-01

      To cchris: the "1 per line" box was never checked.  But thanks for the suggestion anyway.

      To Fool4UAnyway:
      Hmmm... interesting.  I did a bit of experimenting and confirmed exactly what you are saying about the selection changing.  That's indeed why only one column of spaces got replaced.  I don't know if that was the intended functionality or not, but it seems obvious to me that text which is selected when an operation is initiated should remain selected while that operation is taking place.  The behaviour you pointed out (selected text becoming invisibly unselected) seems very counter-intuitive to me.

      I've tried working with Notepad++'s "regular expressions" in the past and found them almost impossible to use.  Things that I have tried to do with regexes that I *know* work in Perl or Awk do not work in Notepad++, and leave me trying repeatedly to tweak spaces or periods or other characters to trick Notepad++ into doing what I want it to do.  I finally gave it up as a lost cause several months ago, and I do not even attempt to use them any more.

      Selecting just the column of spaces and using Alt-C as you suggest did exactly what I needed.  This is probably the solution I should have used from the start, except that I was trying to "kill two birds with one stone" and replace both columns of spaces with a single operation.  In hindsight, it would have been quicker to do it this way... :P

      Thank you very, VERY much for your help!  Not only did you tell me what I needed to know, but you gave me a glimpse into the internal workings of Notepad++ as well.

       
      • Fool4UAnyway
        Fool4UAnyway
        2009-07-01

        >> "
        I don't know if that was the intended functionality or not, but it seems obvious to me that text which is selected when an operation is initiated should remain selected while that operation is taking place. The behaviour you pointed out (selected text becoming invisibly unselected) seems very counter-intuitive to me.
        " <<

        Well, some things that do not work as expected may turn out helpful in other situations.
        If you know (the causes of) awkward behavior, you might get to know how to evoke it and make use of it.

        The same goes for regular expressions and the "hidden" ability for Notepad++'s regex engine to perform multiline operations (on some occasions).

        >> "
        Selecting just the column of spaces and using Alt-C as you suggest did exactly what I needed. ... In hindsight, it would have been quicker to do it this way... :P
        " <<

        Well, cutting, copying and pasting Column Block Selections may work very, very slow in Notepad++, although I'm not sure if the same goes for the Column Editor.

        I'd go for using a regex to do what you want, to perform as much operations as possible in one pass, whether your layout is fixed (where Alt+C might also do), or non-fixed.

        If you want those columns
        xyz 123 abc def
        starting from position 11
        to be converted to
        "xyz","123","abc def"

        you could use the following regular expression in the Find field
        ^(..........)([^ ]+) ([^ ]+) ([^ ]+ ([^ ]+)

        and enter the following expression in the Replace field
        \1"\2","\3","\4"

        This regex just "expects" to always have a space character in the third column:

        ^ ___________ search from/for the start of the line
        (..........) _ search and find the first ten characters, remember these as the first grouped expression
        [^ ]+ _____ search for any consecutive string of non-space characters
        _ _______ search for a space character
        ([^ ]+ ([^ ]+) _ remember the next two words as the fourth grouped expression ("column 3")

        You might add $ to the regex to (search for the) end (of) the line if column 3 is the last column on the line.

        \1 ____ Re-place the first grouped expression, i.e. the first ten characters
        " _____ Insert " before the first column
        \2 ____ Re-place the second grouped expression, i.e. the first column (xyz)
        "," ____ This is what you want the space character(s) to be replaced by
        \3 ____ second column (123)
        \4 ____ third column (abc def)
        " _____ append " to the third column

        Of course, you can do this with (almost) any number of columns.

         
        • Fool4UAnyway
          Fool4UAnyway
          2009-07-01

          If you text layout has fixed numbers of columns / positions, you could simply use the corresponding number of dots in the regular expression:

          Find:
          ^(..........)(...) (...) (... ...+)

          This regex will also do if there are trailing spaces in the columns, which won't be accepted by the [^ ] expression.

          123 xyz abc def
          12_ x__ ab d___

          If there are trailing spaces, but you won't need or want to keep them, you could remove them as well in a single pass. Just add a + sign after each column separating space character.

          Find:
          ^(..........)([^ ]+) +([^ ]+) +([^ ]+ ([^ ]+)

           
          • Fool4UAnyway
            Fool4UAnyway
            2009-07-01

            > If you text layout has fixed numbers of columns / positions, you could simply
            > use the corresponding number of dots in the regular expression:
            >
            > Find:
            > ^(..........)(...) (...) (... ...+)

            Of course, this should have been
            ^(..........)(...) (...) (.......)

            Not a + at the end, and just a dot for each character, if the space characters can also be at any position in the third column (or aren't present at all).

             
  • cchris
    cchris
    2012-06-03

    Using the enhanced regular expressions in N++, you can emulate column mode selection S/R using line selection instead, and
    searching .^(.{27,40}?)toto
    Replace with \1tata
    That will change toto to tata, but only if between 27 and 40 chars that don't match lie before. Don't check ". matches newline".

    CChris