On 04/22/2010 03:37 PM, Peng Yu wrote:
For exmaple, something like [7] [2-8] [2,4,8-10] in the
maintext represent what articles that are listed in the
bibliography are cited. Now, I want to search for where it
cites citation number 7 in the maintext (in this example,
it is cited the three places in the maintext).

Or am I missing something. is 2-8 also valid for 7? If so, I
think you are out of luck for regex.

2-8 is also valid for 7.

Is there anything that are more powerful than regex available
in vim that can handle this case?

Not that I know of.  To tackle the problem, I'd likely
create a search-function that looks for matches of the form

  /\[\(\%(\d\+\%(-\d\+\)\=,\)*\%(\d\+\%(-\d\+\)\=\)]\)/

which should find all things that look like footnotes in
your text.  Then split them on the comma, returning a list
of either pages or page-ranges, then if any of them have a
"-" in them, check if the target value is within that range,
otherwise just compare for equality.  If you don't find any
match within the split-list, continue searching to the next
match of the above pattern.  The pseduo-code (untested)
would look something like

  function! FootSearch(fn)
    let re='\[\(\%(\d\+\%(-\d\+\)\=,\)*\%(\d\+\%(-\d\+\)\=\)]\)'
    let newmatch=searchpos(re, 's')
    let initialmatch=newmatch
    while newmatch != [0,0]
      let [r,c]=newmatch
      " m = the contents of the match
      " with the "[" and "]" stripped off
      " using the "[1:-2]"
      let m=matchstr(getline(r)[c:], re)[1:-2]
      for bit in split(m, ',')
        " deal with any comma-separated list
        " of pages or ranges
        if bit=~'.*-.*'
          " if it's a page-range
          " pull the start/end
          let [st, end]=split(bit, '-')
          if st <= fn && fn <= end
            " we're between the pages in that range
            return
          endif
        else
          if bit == fn
            " it's an exact match
            " might want do strip leading zeros
            " from bit in case you search for "4"
            " and the text contains [04]
            return
          endif
        endif
      endfor
      " if we've not returned by now,
      " this footnote doesn't match
      " so find the next and keep going
      let newmatch=searchpos(re, 's')
      if newmatch == initialmatch
        " we've found the first match again
        " so we've likely looped around
        " and we've not returned yet
        " so prevent an infinite loop
        break
      endif
      let [r,c]=newmatch
    endwhile
  endfunction

Any bugs are yours to keep ;-)  But that's the general idea I'd use.

-tim




--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

Subscription settings: http://groups.google.com/group/vim_use/subscribe?hl=en

Reply via email to