regex - How do you perform a 2d search in vim?

08
2014-07
  • Brian Minton

    I'm looking for lines in a file that match a 2-dimensional pattern.

    For instance, given the following input file:

    aaaba
    aabaa
    aaaba
    aaaaa
    aaaaa
    

    I'd like to use a pattern like

    ab
    ba
    ab
    

    to match on the top 3 lines. Ideally, I'd like to be able to make a substitution with that pattern, for instance, replacing it with

    ba
    ab
    ba
    
  • Answers
  • Ingo Karkat

    This cannot be done via regular expressions alone. You'd need a special atom that works like a capture group, but instead captures the column, and then a corresponding atom for recall. Best you can do is matching each row on a subsequent line, for your example

    /ab\ze.*\n.*ba.*\n.*ab/
    

    With that, not just lines that match the block's lines on their own are matched, but all occurrences that contain the block's text, though not just with the same vertical alignment, and only the first line's match is highlighted. My SearchHighlighting plugin provides this functionality (mapped to {Visual}*), too.

    If that doesn't suffice (you can use the /c flag on :substitute to manually verify and acknowledge each match), you have to build your own search (and substitute) infrastructure, i.e. equivalents of /, n / N, and :s, and do the additional assertion for block-alignment in Vimscript.


  • Related Question

    regex - How do I do a block search-and-replace with Vim?
  • Evan Carroll

    I have text in Vim

    1. hit Ctrl+V to put VIm in block mode
    2. highlight the text I want
    3. type : this gives the this prompt :'<,'>
    4. I add to the prompt my regex s/ /*/g. This leaves me with :'<,'>s/ /*/g and the text highlighted
    5. I hit enter

    Unfortunately, it operates on the whole line for the block, not just the block. Is there anyway to do a block search and replace?


  • Related Answers
  • DaveParillo

    When using ex commands in visual block mode, :, they always operate on the whole line. There are two ways around this:

    1. The \%V atom will match only inside the visual area. Try

      :'<,'>s/\%V /*/g
      

      See :help %V

    2. There are special visual versions of some commands, live v_s or v_r. See :help visual-operators