vim: how to use back reference to compare strings?

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

vim: how to use back reference to compare strings?

ping song

hi guys:
I run into a scenario that , I need to compare 2 part of the regex string in one line :

"abc123456 bla bla bla abc1234"

so I'm thinking, can we use the backreference, to compare the first abc\d\+ with the second one and only print out a message in case we detect the different ones ? preferably if this can be done with one command...

thanks!

 

--
--
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
 
---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

Marcin Szamotulski
Hi,

I am not sure if I understand you correctly but you can use \(...\) and
and then reuse it with \1 (it matches the same string as what \(...\)
have matched).

Regards,
Marcin



On 00:44 Sat 10 Aug     , ping song wrote:

> hi guys:
> I run into a scenario that , I need to compare 2 part of the regex string
> in one line :
>
> "abc123456 bla bla bla abc1234"
>
> so I'm thinking, can we use the backreference, to compare the first abc\d\+
> with the second one and only print out a message in case we detect the
> different ones ? preferably if this can be done with one command...
>
> thanks!
>
> --
> --
> 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
>
> ---
> You received this message because you are subscribed to the Google Groups "vim_use" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.
Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

ping song
thanks. yes I know we can use that way(/1 /2 ..etc).
what I meant is, how to use these to actually do the compare in a vim ex command line?
sth like :

:g#\(abc\d\+) bla bla \(abc\d\+\)#if /1 != /2 then echo "found a diff !"

of course this doesn't work but just some fake code to clarify what I meant



On Sat, Aug 10, 2013 at 3:30 AM, Marcin Szamotulski <[hidden email]> wrote:
Hi,

I am not sure if I understand you correctly but you can use \(...\) and
and then reuse it with \1 (it matches the same string as what \(...\)
have matched).

Regards,
Marcin



On 00:44 Sat 10 Aug     , ping song wrote:
> hi guys:
> I run into a scenario that , I need to compare 2 part of the regex string
> in one line :
>
> "abc123456 bla bla bla abc1234"
>
> so I'm thinking, can we use the backreference, to compare the first abc\d\+
> with the second one and only print out a message in case we detect the
> different ones ? preferably if this can be done with one command...
>
> thanks!
>
> --
> --
> 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
>
> ---
> You received this message because you are subscribed to the Google Groups "vim_use" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.

--
--
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
 
---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

Niklas Reinhart-2
Hi,

this works for me:

        abc\(\d\+\).*abc\1\@!

Regards

Niklas


Am Sat, 10 Aug 2013 16:45:30 -0400
schrieb Ping Song <[hidden email]>:

> thanks. yes I know we can use that way(/1 /2 ..etc).
> what I meant is, how to use these to actually do the compare in a vim
> ex command line? sth like :
>
> :g#\(abc\d\+) bla bla \(abc\d\+\)#if /1 != /2 then echo "found a
> diff !"
>
> of course this doesn't work but just some fake code to clarify what I
> meant
>
>
>
> On Sat, Aug 10, 2013 at 3:30 AM, Marcin Szamotulski
> <[hidden email]> wrote: Hi,
>
> I am not sure if I understand you correctly but you can use \(...\)
> and and then reuse it with \1 (it matches the same string as what
> \(...\) have matched).
>
> Regards,
> Marcin
>
>
>
> On 00:44 Sat 10 Aug     , ping song wrote:
> > hi guys:
> > I run into a scenario that , I need to compare 2 part of the regex
> > string in one line :
> >
> > "abc123456 bla bla bla abc1234"
> >
> > so I'm thinking, can we use the backreference, to compare the first
> > abc\d\+ with the second one and only print out a message in case we
> > detect the different ones ? preferably if this can be done with one
> > command...
> >
> > thanks!
> >
> > --
> > --
> > 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
> >
> > ---
> > You received this message because you are subscribed to the Google
> > Groups "vim_use" group. To unsubscribe from this group and stop
> > receiving emails from it, send an email to
> > [hidden email]. For more options, visit
> > https://groups.google.com/groups/opt_out.
> >
> >
>
> --
> --
> 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
>
> ---
> You received this message because you are subscribed to the Google
> Groups "vim_use" group. To unsubscribe from this group and stop
> receiving emails from it, send an email to
> [hidden email]. For more options, visit
> https://groups.google.com/groups/opt_out.
>

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.


Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

John Little-4
In reply to this post by ping song
On Sunday, August 11, 2013 8:45:30 AM UTC+12, ping wrote:
>
> what I meant is, how to use these to actually do the compare in a vim ex command line?
> sth like :
>
> :g#\(abc\d\+) bla bla \(abc\d\+\)#if /1 != /2 then echo "found a diff !"

What you want is for submatch() to work in the context of :g.  (Where's perl's $1, $2 ... when you want them...)  You could fake it using a function and a substitute with the n flag:

func! Diff(a,b)
    if a:a != a:b
        echo "found a diff!"
    endif
endfunc

:g#\(abc\d\+) bla bla \(abc\d\+\)#s//\=Diff(submatch(1),submatch(2))/n

Regards, John Little

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.
Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

ping song
This looks nice, will test it out



On Aug 10, 2013, at 21:06, John Little <[hidden email]> wrote:

> On Sunday, August 11, 2013 8:45:30 AM UTC+12, ping wrote:
>>
>> what I meant is, how to use these to actually do the compare in a vim ex command line?
>> sth like :
>>
>> :g#\(abc\d\+) bla bla \(abc\d\+\)#if /1 != /2 then echo "found a diff !"
>
> What you want is for submatch() to work in the context of :g.  (Where's perl's $1, $2 ... when you want them...)  You could fake it using a function and a substitute with the n flag:
>
> func! Diff(a,b)
>    if a:a != a:b
>        echo "found a diff!"
>    endif
> endfunc
>
> :g#\(abc\d\+) bla bla \(abc\d\+\)#s//\=Diff(submatch(1),submatch(2))/n
>
> Regards, John Little
>
> --
> --
> 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
>
> ---
> You received this message because you are subscribed to the Google Groups "vim_use" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
> For more options, visit https://groups.google.com/groups/opt_out.

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.
Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

ping song
In reply to this post by John Little-4
I tested this again these test lines, doesn't work.

abc123 bla bla bla abc123 bla bla
abc123 bla bla bla abc1234 bla bla
abc123 bla bla bla abc123 bla bla
abc123 bla bla bla abc1234 bla bla
abc123 bla bla bla abc123 bla bla

:g#\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)#s//\=Diff(submatch(1),submatch(2))/n

I got : "5 substitutions in 5 lines". no message got printed out...
any idea of what I missed here?

thanks anyway.


On Sat, Aug 10, 2013 at 9:06 PM, John Little <[hidden email]> wrote:
On Sunday, August 11, 2013 8:45:30 AM UTC+12, ping wrote:
>
> what I meant is, how to use these to actually do the compare in a vim ex command line?
> sth like :
>
> :g#\(abc\d\+) bla bla \(abc\d\+\)#if /1 != /2 then echo "found a diff !"

What you want is for submatch() to work in the context of :g.  (Where's perl's $1, $2 ... when you want them...)  You could fake it using a function and a substitute with the n flag:

func! Diff(a,b)
    if a:a != a:b
        echo "found a diff!"
    endif
endfunc

:g#\(abc\d\+) bla bla \(abc\d\+\)#s//\=Diff(submatch(1),submatch(2))/n

Regards, John Little

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.

--
--
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
 
---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

ping song
In reply to this post by Niklas Reinhart-2
hi: 
thanks for the response, this look much shorter!
but this doesn't work either...

:g/\(abc\d\+\).*\1\@!\(.*\)
1 abc123 bla bla bla abc123 bla bla
2 abc123 bla bla bla abc1234 bla bla
3 abc123 bla bla bla abc123 bla bla
4 abc123 bla bla bla abc1234 bla bla
5 abc123 bla bla bla abc123 bla bla

I'm expecting to see only line 2&4...

any idea?

regards
ping



On Sat, Aug 10, 2013 at 5:11 PM, Niklas Reinhart <[hidden email]> wrote:
Hi,

this works for me:

        abc\(\d\+\).*abc\1\@!

Regards

Niklas


Am Sat, 10 Aug 2013 16:45:30 -0400
schrieb Ping Song <[hidden email]>:

> thanks. yes I know we can use that way(/1 /2 ..etc).
> what I meant is, how to use these to actually do the compare in a vim
> ex command line? sth like :
>
> :g#\(abc\d\+) bla bla \(abc\d\+\)#if /1 != /2 then echo "found a
> diff !"
>
> of course this doesn't work but just some fake code to clarify what I
> meant
>
>
>
> On Sat, Aug 10, 2013 at 3:30 AM, Marcin Szamotulski
> <[hidden email]> wrote: Hi,
>
> I am not sure if I understand you correctly but you can use \(...\)
> and and then reuse it with \1 (it matches the same string as what
> \(...\) have matched).
>
> Regards,
> Marcin
>
>
>
> On 00:44 Sat 10 Aug     , ping song wrote:
> > hi guys:
> > I run into a scenario that , I need to compare 2 part of the regex
> > string in one line :
> >
> > "abc123456 bla bla bla abc1234"
> >
> > so I'm thinking, can we use the backreference, to compare the first
> > abc\d\+ with the second one and only print out a message in case we
> > detect the different ones ? preferably if this can be done with one
> > command...
> >
> > thanks!
> >
> > --
> > --
> > 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
> >
> > ---
> > You received this message because you are subscribed to the Google
> > Groups "vim_use" group. To unsubscribe from this group and stop
> > receiving emails from it, send an email to
> > [hidden email]. For more options, visit
> > https://groups.google.com/groups/opt_out.
> >
> >
>
> --
> --
> 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
>
> ---
> You received this message because you are subscribed to the Google
> Groups "vim_use" group. To unsubscribe from this group and stop
> receiving emails from it, send an email to
> [hidden email]. For more options, visit
> https://groups.google.com/groups/opt_out.
>

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.



--
--
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
 
---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.
Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

ping song
I also checked "help \@!", and got this:

Useful example: to find "foo" in a line that does not contain "bar":
/^\%(.*bar\)\@!.*\zsfoo

but it seems, it desn't work with back-ref ...

guys, who can help explaining these ?


On Sat, Aug 10, 2013 at 10:50 PM, ping song <[hidden email]> wrote:
hi: 
thanks for the response, this look much shorter!
but this doesn't work either...

:g/\(abc\d\+\).*\1\@!\(.*\)
1 abc123 bla bla bla abc123 bla bla
2 abc123 bla bla bla abc1234 bla bla
3 abc123 bla bla bla abc123 bla bla
4 abc123 bla bla bla abc1234 bla bla
5 abc123 bla bla bla abc123 bla bla

I'm expecting to see only line 2&4...

any idea?

regards
ping



On Sat, Aug 10, 2013 at 5:11 PM, Niklas Reinhart <[hidden email]> wrote:
Hi,

this works for me:

        abc\(\d\+\).*abc\1\@!

Regards

Niklas


Am Sat, 10 Aug 2013 16:45:30 -0400
schrieb Ping Song <[hidden email]>:

> thanks. yes I know we can use that way(/1 /2 ..etc).
> what I meant is, how to use these to actually do the compare in a vim
> ex command line? sth like :
>
> :g#\(abc\d\+) bla bla \(abc\d\+\)#if /1 != /2 then echo "found a
> diff !"
>
> of course this doesn't work but just some fake code to clarify what I
> meant
>
>
>
> On Sat, Aug 10, 2013 at 3:30 AM, Marcin Szamotulski
> <[hidden email]> wrote: Hi,
>
> I am not sure if I understand you correctly but you can use \(...\)
> and and then reuse it with \1 (it matches the same string as what
> \(...\) have matched).
>
> Regards,
> Marcin
>
>
>
> On 00:44 Sat 10 Aug     , ping song wrote:
> > hi guys:
> > I run into a scenario that , I need to compare 2 part of the regex
> > string in one line :
> >
> > "abc123456 bla bla bla abc1234"
> >
> > so I'm thinking, can we use the backreference, to compare the first
> > abc\d\+ with the second one and only print out a message in case we
> > detect the different ones ? preferably if this can be done with one
> > command...
> >
> > thanks!
> >
> > --
> > --
> > 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
> >
> > ---
> > You received this message because you are subscribed to the Google
> > Groups "vim_use" group. To unsubscribe from this group and stop
> > receiving emails from it, send an email to
> > [hidden email]. For more options, visit
> > https://groups.google.com/groups/opt_out.
> >
> >
>
> --
> --
> 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
>
> ---
> You received this message because you are subscribed to the Google
> Groups "vim_use" group. To unsubscribe from this group and stop
> receiving emails from it, send an email to
> [hidden email]. For more options, visit
> https://groups.google.com/groups/opt_out.
>

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.




--
--
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
 
---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.
 
 
Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

John Little-4
In reply to this post by ping song
On Sunday, August 11, 2013 2:44:28 PM UTC+12, ping wrote:
> any idea of what I missed here?

With

:g#\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)#s//\=Diff(submatch(1),submatch(2))/n

I get all lines reporting a difference, changing the echo to

   echo "found a diff!" a:a a:b

shows me why.

Back references are numbered from the left, by their opening \(.  Your pattern is

   \(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)

where you've bracketed the middle bit, so that's returned by submatch(2); you want to compare matches 1 and 3. Using

:g#\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)#s//\=Diff(submatch(1),submatch(3))/n

I get

found a diff! abc123 abc1234
found a diff! abc123 abc1234
5 substitutions on 5 lines

It's an ugly hack, any way.  I've just noticed that the matchlist() function gives access to submatches, a function using that would be cleaner:

func! Diff2(pat)
    call setpos('.',[0, 1, 1, 0]) " go to beginning
    while search(a:pat, 'W')
        let l = matchlist(getline('.'),a:pat)
        if len(l) >= 4 && l[1] != l[3]
            echo 'found a diff:' l[1] l[3]
        endif
    endwhile
endfunc

:call Diff2('\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)')

Regards, John Little

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.


Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

Niklas Reinhart-2
In reply to this post by ping song
Still a one-liner but returns only lines 2+4 for me:
       
        :g/abc\(\d\+).*abc\1\d

But depending on the pattern of your actual use case this may still not
suffice.

Regards,
Niklas


Am Sat, 10 Aug 2013 22:50:27 -0400
schrieb ping song <[hidden email]>:

> hi:
> thanks for the response, this look much shorter!
> but this doesn't work either...
>
> :g/\(abc\d\+\).*\1\@!\(.*\)
> 1 abc123 bla bla bla abc123 bla bla
> 2 abc123 bla bla bla abc1234 bla bla
> 3 abc123 bla bla bla abc123 bla bla
> 4 abc123 bla bla bla abc1234 bla bla
> 5 abc123 bla bla bla abc123 bla bla
>
> I'm expecting to see only line 2&4...
>
> any idea?
>
> regards
> ping
>
>
>
> On Sat, Aug 10, 2013 at 5:11 PM, Niklas Reinhart
> <[hidden email]>wrote:
>
> > Hi,
> >
> > this works for me:
> >
> >         abc\(\d\+\).*abc\1\@!
> >
> > Regards
> >
> > Niklas
> >
> >
> > Am Sat, 10 Aug 2013 16:45:30 -0400
> > schrieb Ping Song <[hidden email]>:
> >
> > > thanks. yes I know we can use that way(/1 /2 ..etc).
> > > what I meant is, how to use these to actually do the compare in a
> > > vim ex command line? sth like :
> > >
> > > :g#\(abc\d\+) bla bla \(abc\d\+\)#if /1 != /2 then echo "found a
> > > diff !"
> > >
> > > of course this doesn't work but just some fake code to clarify
> > > what I meant
> > >
> > >
> > >
> > > On Sat, Aug 10, 2013 at 3:30 AM, Marcin Szamotulski
> > > <[hidden email]> wrote: Hi,
> > >
> > > I am not sure if I understand you correctly but you can use
> > > \(...\) and and then reuse it with \1 (it matches the same string
> > > as what \(...\) have matched).
> > >
> > > Regards,
> > > Marcin
> > >
> > >
> > >
> > > On 00:44 Sat 10 Aug     , ping song wrote:
> > > > hi guys:
> > > > I run into a scenario that , I need to compare 2 part of the
> > > > regex string in one line :
> > > >
> > > > "abc123456 bla bla bla abc1234"
> > > >
> > > > so I'm thinking, can we use the backreference, to compare the
> > > > first abc\d\+ with the second one and only print out a message
> > > > in case we detect the different ones ? preferably if this can
> > > > be done with one command...
> > > >
> > > > thanks!
> > > >
> > > > --
> > > > --
> > > > 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
> > > >
> > > > ---
> > > > You received this message because you are subscribed to the
> > > > Google Groups "vim_use" group. To unsubscribe from this group
> > > > and stop receiving emails from it, send an email to
> > > > [hidden email]. For more options, visit
> > > > https://groups.google.com/groups/opt_out.
> > > >
> > > >
> > >
> > > --
> > > --
> > > 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
> > >
> > > ---
> > > You received this message because you are subscribed to the Google
> > > Groups "vim_use" group. To unsubscribe from this group and stop
> > > receiving emails from it, send an email to
> > > [hidden email]. For more options, visit
> > > https://groups.google.com/groups/opt_out.
> > >
> >
> > --
> > --
> > 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
> >
> > ---
> > You received this message because you are subscribed to the Google
> > Groups "vim_use" group.
> > To unsubscribe from this group and stop receiving emails from it,
> > send an email to [hidden email].
> > For more options, visit https://groups.google.com/groups/opt_out.
> >
> >
> >
>

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.


Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

Benjamin R. Haskell-8
In reply to this post by ping song
[Please bottom post, per the footer]

On Sat, 10 Aug 2013, ping song wrote:

> I tested this again these test lines, doesn't work.
>
> abc123 bla bla bla abc123 bla bla
> abc123 bla bla bla abc1234 bla bla
> abc123 bla bla bla abc123 bla bla
> abc123 bla bla bla abc1234 bla bla
> abc123 bla bla bla abc123 bla bla
>
> :g#\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)#s//\=Diff(submatch(1),submatch(2))/n
>
> I got : "5 substitutions in 5 lines". no message got printed out...
> any idea of what I missed here?
>
> thanks anyway.

Try:

:g#\(abc\d\+\)\>.*\<\%(\1\>\)\@!\(abc\d\+\)#

Here's a diagram. (Not sure if I like it; trying this out):

    ┌──────────┬ an identifier
    │          ├ ending w/a word boundary
    │          │
    │          │ ┌ (don't need to capture)
    │          │ │ ┌ start of a word
    │          │ │ │ ┌ non-capturing (but needed for grouping)
    │          │ │ │ │
    │          │ │ │ │  ┌─────┬ 1st identifier we found
    │          │ │ │ │  │ ┌───┼ followed by a word boundary
    │          │ │ │ │  │ │   ├ doesn't match here
    │          │ │ │ │  │ │   │
    │          │ │ │ │  │ │   │  ┌ but there is *an* identifier
    │          │ │ │ │  │ │   │  │
    ├─────────┐├┐├┐├┐├─┐├┐├┐  ├─┐├─────────┐
:g#\(abc\d\+\)\>.*\<\%(\1\>\)\@!\(abc\d\+\)#

In English:

Find lines where:
   We capture an identifier.
   Match some stuff between.
   At a word boundary where the captured identifier doesn't match:
     There is some identifier.


Regular expressions have a bad tendency towards being "write-only".  I'm
guessing the following code, if you're familiar with VimL, will be more
maintainable, and probably easier to extend.  It also dumps everything in a
quickfix list and opens the window if anything matches -- look at the lines
with 'qf' on them if you don't like quickfix:

fun! FindDiffs()
   let i = 1
   let l = line('$')
   let buf = bufnr('.')
   let qf = []
   while i < l
     let m = matchlist(getline(i), '\(abc\d\+\).*\(abc\d\+\)')
     if len(m)
       let [a, b] = m[1:2]
       if a != b
         " when not using qf, echo it: echom a '!=' b 'on line' i
         call add(qf, {'bufnr': buf, 'lnum': i, 'text': a.' != '.b, 'type': 'W'})
       end
     end
     let i += 1
   endw
   call setqflist(qf) | cw
endf

--
Best,
Ben

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.


Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

ping song
In reply to this post by John Little-4
thanks again John!

I tried your 1st amendment , which is:
:g#\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)#s//\=Diff(submatch(1),submatch(3))/n

really wireld , I still got the same result -- a message saying: "5 substitutions in 5 lines", nothing got "echo"ed out...
I copied from your email and pasted into my vim, are you sure it works in your vim ?

your second solution definitely works fine.
but, it doesn't look "simpler" to me (vimL beginner level) at all... I could understand the 1st oneliner better than this function -- I hope I can understand it though.



On Sun, Aug 11, 2013 at 3:08 AM, John Little <[hidden email]> wrote:
On Sunday, August 11, 2013 2:44:28 PM UTC+12, ping wrote:
> any idea of what I missed here?

With

:g#\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)#s//\=Diff(submatch(1),submatch(2))/n

I get all lines reporting a difference, changing the echo to

   echo "found a diff!" a:a a:b

shows me why.

Back references are numbered from the left, by their opening \(.  Your pattern is

   \(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)

where you've bracketed the middle bit, so that's returned by submatch(2); you want to compare matches 1 and 3. Using

:g#\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)#s//\=Diff(submatch(1),submatch(3))/n

I get

found a diff! abc123 abc1234
found a diff! abc123 abc1234
5 substitutions on 5 lines

It's an ugly hack, any way.  I've just noticed that the matchlist() function gives access to submatches, a function using that would be cleaner:

func! Diff2(pat)
    call setpos('.',[0, 1, 1, 0]) " go to beginning
    while search(a:pat, 'W')
        let l = matchlist(getline('.'),a:pat)
        if len(l) >= 4 && l[1] != l[3]
            echo 'found a diff:' l[1] l[3]
        endif
    endwhile
endfunc

:call Diff2('\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)')

Regards, John Little

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.



--
--
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
 
---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.
Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

Christian Brabandt
On Mon, August 12, 2013 07:03, ping song wrote:
> thanks again John!
>
> I tried your 1st amendment , which is:
> :g#\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)#s//\=Diff(submatch(1),submatch(3))/n
>
> really wireld , I still got the same result -- a message saying: "5
> substitutions in 5 lines", nothing got "echo"ed out...

You need a recent Vim, which means Vim 7.4 or 7.3.5XX or newer. Older Vims
did not evaluate the second part of the :s command when given the 'n'
flag.

regards,
Christian

--
--
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

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.
Reply | Threaded
Open this post in threaded view
|

Re: vim: how to use back reference to compare strings?

ping song
In reply to this post by Benjamin R. Haskell-8
these are really cool , working , and good stuff to learn...
I'll need to take some time to learn from here...will consult you shortly with some questions..

thanks!



On Sun, Aug 11, 2013 at 3:52 AM, Benjamin R. Haskell <[hidden email]> wrote:
[Please bottom post, per the footer]


On Sat, 10 Aug 2013, ping song wrote:

I tested this again these test lines, doesn't work.

abc123 bla bla bla abc123 bla bla
abc123 bla bla bla abc1234 bla bla
abc123 bla bla bla abc123 bla bla
abc123 bla bla bla abc1234 bla bla
abc123 bla bla bla abc123 bla bla

:g#\(abc\d\+\)\(.*\)\(abc\d\+\)\(.*\)#s//\=Diff(submatch(1),submatch(2))/n

I got : "5 substitutions in 5 lines". no message got printed out...
any idea of what I missed here?

thanks anyway.

Try:

:g#\(abc\d\+\)\>.*\<\%(\1\>\)\@!\(abc\d\+\)#

Here's a diagram. (Not sure if I like it; trying this out):

   ┌──────────┬ an identifier
   │          ├ ending w/a word boundary
   │          │
   │          │ ┌ (don't need to capture)
   │          │ │ ┌ start of a word
   │          │ │ │ ┌ non-capturing (but needed for grouping)
   │          │ │ │ │
   │          │ │ │ │  ┌─────┬ 1st identifier we found
   │          │ │ │ │  │ ┌───┼ followed by a word boundary
   │          │ │ │ │  │ │   ├ doesn't match here
   │          │ │ │ │  │ │   │
   │          │ │ │ │  │ │   │  ┌ but there is *an* identifier
   │          │ │ │ │  │ │   │  │
   ├─────────┐├┐├┐├┐├─┐├┐├┐  ├─┐├─────────┐
:g#\(abc\d\+\)\>.*\<\%(\1\>\)\@!\(abc\d\+\)#

In English:

Find lines where:
  We capture an identifier.
  Match some stuff between.
  At a word boundary where the captured identifier doesn't match:
    There is some identifier.


Regular expressions have a bad tendency towards being "write-only".  I'm guessing the following code, if you're familiar with VimL, will be more maintainable, and probably easier to extend.  It also dumps everything in a quickfix list and opens the window if anything matches -- look at the lines with 'qf' on them if you don't like quickfix:

fun! FindDiffs()
  let i = 1
  let l = line('$')
  let buf = bufnr('.')
  let qf = []
  while i < l
    let m = matchlist(getline(i), '\(abc\d\+\).*\(abc\d\+\)')
    if len(m)
      let [a, b] = m[1:2]
      if a != b
        " when not using qf, echo it: echom a '!=' b 'on line' i
        call add(qf, {'bufnr': buf, 'lnum': i, 'text': a.' != '.b, 'type': 'W'})
      end
    end
    let i += 1
  endw
  call setqflist(qf) | cw
endf

--
Best,
Ben


--
--
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

--- You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.



--
--
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
 
---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/groups/opt_out.