Vim:如果 submatch(1) 为空,则删除与模式匹配的文本

发布于 2024-12-26 20:47:04 字数 1316 浏览 1 评论 0原文

此命令行解析联系人列表文档,其中可能列出也可能没有列出电话、电子邮件或网络。如果它具有全部三个,那么一切都很好 - 在数据上传行的末尾附加 FormatContact() 的返回值:

silent!/^\d/+1|ki|/\n^\d\|\%$/-1|kj|'i,'jd|let @a = substitute(@",'\s*Phone: \([^,]*\)\_.*','\1',"")|let @b = substitute(@",'^\_.*E-mail:\s\[\d*\]\([[email protected]]*\)\_.*','\1',"")|let @c = substitute(@",'^\_.*Web site:\s*\[\d*\]\([-_.:/0-9a-zA-Z]*\)\_.*','\1',"")|?^\d\+?s/$/\=','.FormatContact(@a,@b,@c)

或者,分解:

silent!/^\d/+1|ki|/\n^\d\|\%$/-1|kj|'i,'jd
let @a = substitute(@",'\s*Phone: \([^,]*\)\_.*','\1',"")
let @b = substitute(@",'^\_.*E-mail:\s\[\d*\]\([[email protected]]*\)\_.*','\1',"")
let @c = substitute(@",'^\_.*Web site:\s*\[\d*\]\([-_.:/0-9a-zA-Z]*\)\_.*','\1',"")
?^\d\+?s/$/\=','.FormatContact(@a,@b,@c)

我创建了三个单独的搜索,以免在一个原子的情况下使任何一个搜索失败无法匹配,因为同样,每个联系人的联系信息可能存在也可能不存在。

解决方案创建的问题是,当模式不匹配时,我将整个@“放入@a中。相反,当匹配不发生时,我需要它为空。我需要表示的每个变量(电话、电子邮件、网络)无论它是否为空,

  1. 我都没有看到可以在替换函数中设置的标志。 会这样做。
  2. 如果 \1 为空,有没有办法返回“”?
  3. 有没有办法创建一个可选原子,以便搜索查询仍然可以解释空匹配,以便正确地将其记录为空?

This command line parses a contact list document that may or may not have either a phone, email or web listed. If it has all three then everything works great - appending the return from the FormatContact() at the end of the line for data uploading:

silent!/^\d/+1|ki|/\n^\d\|\%$/-1|kj|'i,'jd|let @a = substitute(@",'\s*Phone: \([^,]*\)\_.*','\1',"")|let @b = substitute(@",'^\_.*E-mail:\s\[\d*\]\([[email protected]]*\)\_.*','\1',"")|let @c = substitute(@",'^\_.*Web site:\s*\[\d*\]\([-_.:/0-9a-zA-Z]*\)\_.*','\1',"")|?^\d\+?s/$/\=','.FormatContact(@a,@b,@c)

or, broken down:

silent!/^\d/+1|ki|/\n^\d\|\%$/-1|kj|'i,'jd
let @a = substitute(@",'\s*Phone: \([^,]*\)\_.*','\1',"")
let @b = substitute(@",'^\_.*E-mail:\s\[\d*\]\([[email protected]]*\)\_.*','\1',"")
let @c = substitute(@",'^\_.*Web site:\s*\[\d*\]\([-_.:/0-9a-zA-Z]*\)\_.*','\1',"")
?^\d\+?s/$/\=','.FormatContact(@a,@b,@c)

I created three separate searches so as not to make any ONE search fail if one atom failed to match because - again - the contact info may or may not exist per contact.

The Problem that solution created was that when the pattern does not match I get the whole @" into @a. Instead, I need it to be empty when the match does not occur. I need each variable represented (phone,email,web) whether it be empty or not.

  1. I see no flags that can be set in the substitution function that
    will do this.
  2. Is there a way to return "" if \1 is empty?
  3. Is there a way to create an optional atom so the search query(ies) could still account for an empty match so as to properly record it as empty?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我喜欢麦丽素 2025-01-02 20:47:04

而不是使用替换来替换整个捕获的文本
有了感兴趣的部分,就可以只匹配目标部分。不像
替换例程,匹配的例程要么找到符合的文本
到给定的模式,或报告没有这样的文本。因此,
优先使用 matchstr() 函数而不是 substitute()
问题中列出的解析代码可以更改如下:

let @a = matchstr(@", '\<Phone:\s*\zs[^,]*')
let @b = matchstr(@", '\<E-mail:\s*\[\d*\]\zs[[email protected]]*')
let @c = matchstr(@", '\<Web site:\s*\[\d*\]\zs[-_.:/0-9a-zA-Z]*')

Instead of using substitutions that replace the whole captured text
with its part of interest, one can match only that target part. Unlike
substitution routines, matching ones either locate the text conforming
to the given pattern, or report that there is no such text. Thus,
using the matchstr() function in preference to substitute(), the
parsing code listed in the question can be changed as follows:

let @a = matchstr(@", '\<Phone:\s*\zs[^,]*')
let @b = matchstr(@", '\<E-mail:\s*\[\d*\]\zs[[email protected]]*')
let @c = matchstr(@", '\<Web site:\s*\[\d*\]\zs[-_.:/0-9a-zA-Z]*')
归途 2025-01-02 20:47:04

如果您想要逐行处理,请考虑与 :global 结合使用,例如

let @a=""
g/text to match/let @A=substitute(getline("."), '^.*\(' . @/ . '\).*

这将打印包含它的任何行的匹配文本,并用换行符分隔:

echo @a

这里的美妙之处在于您可以使其与最后一个一起使用使用搜索模式非常容易:

g//let @A=substitute(getline("."), '^.*\(' . @/ . '\).*
, '\1\r', '')

这将打印包含它的任何行的匹配文本,并用换行符分隔:


这里的美妙之处在于您可以使其与最后一个一起使用使用搜索模式非常容易:


, '\1\r', '')
, '\1\r', '')

这将打印包含它的任何行的匹配文本,并用换行符分隔:

这里的美妙之处在于您可以使其与最后一个一起使用使用搜索模式非常容易:

Just in case you want linewise processing, consider using in combination with :global, e.g.

let @a=""
g/text to match/let @A=substitute(getline("."), '^.*\(' . @/ . '\).*

This will print the matched text for any line that contained it, separated with newlines:

echo @a

The beautiful thing here, is that you can make it work with the last-used search-pattern very easily:

g//let @A=substitute(getline("."), '^.*\(' . @/ . '\).*
, '\1\r', '')

This will print the matched text for any line that contained it, separated with newlines:


The beautiful thing here, is that you can make it work with the last-used search-pattern very easily:


, '\1\r', '')
, '\1\r', '')

This will print the matched text for any line that contained it, separated with newlines:

The beautiful thing here, is that you can make it work with the last-used search-pattern very easily:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文