regex - sed regex可以模拟后向和前瞻吗?

标签 regex sed awk regex-negation regex-lookarounds

我正在尝试编写一个sed脚本,该脚本将捕获文本文件中的所有“裸” URL并将其替换为<a href=[URL]>[URL]</a>。 “裸露”是指未包装在 anchor 标记内的URL。

我最初的想法是,我应该匹配在它们前面没有“或”并且在它们之后也没有“或”的URL。但是,我很难表达“不要在前面或后面”的概念,因为据我所知sed并不具有先行性或后置性。

输入样例:

[Beginning of File]http://foo.bar arbitrary text
http://test.com other text
<a href="http://foobar.com">http://foobar.com</a>
Nearing end of file!!! http://yahoo.com[End of File]

所需样本输出:
[Beginning of File]<a href="http://foo.bar">http://foo.bar</a> arbitrary text
<a href="http://test.com">http://test.com</a> other text
<a href="http://foo.bar">http://foo.bar</a>
Nearing end of file!!! <a href="http://yahoo.com">http://yahoo.com</a>[End of File]

请注意,第三行未修改,因为它已经在<a href>中。
另一方面,第一行和第二行均被修改。
最后,观察到所有非URL文本均未修改。

最终,我正在尝试执行以下操作:
sed s/[^>"](http:\/\/[^\s]\+)/<a href="\1">\1<\/a>/g 2-7-2013

我首先验证以下内容将正确匹配并删除URL:
sed 's/http:\/\/[^\s]\+//g'

然后,我尝试了此操作,但是它无法匹配以文件/输入开头开头的URL:
sed 's/[^\>"]http:\/\/[^\s]\+//g'

有没有一种方法可以通过模拟lookbehind/lookahead或显式匹配文件开头和文件结尾来解决sed中的问题?

最佳答案

sed是用于在单行上进行简单替换的出色工具,对于任何其他文本操作问题,只需使用awk。

在下面的“开始”部分中检查我正在使用的定义,以查找与URL匹配的正则表达式。它适用于您的示例,但我不知道它是否捕获所有可能的URL格式。即使它不能满足您的需求,也可以。

$ cat file
[Beginning of File]http://foo.bar arbitrary text
http://test.com other text
<a href="http://foobar.com">http://foobar.com</a>
Nearing end of file!!! http://yahoo.com[End of File]
$
$ awk -f tst.awk file
[Beginning of File]<a href="http://foo.bar">http://foo.bar</a> arbitrary text
<a href="http://test.com">http://test.com</a> other text
<a href="http://foobar.com">http://foobar.com</a>
Nearing end of file!!! <a href="http://yahoo.com">http://yahoo.com</a>[End of File]
$
$ cat tst.awk
BEGIN{ urlRe="http:[/][/][[:alnum:]._]+" }
{
    head = ""
    tail = $0
    while ( match(tail,urlRe) ) {
       url  = substr(tail,RSTART,RLENGTH)
       href = "href=\"" url "\""

       if (index(tail,href) == (RSTART - 6) ) {
          # this url is inside href="url" so skip processing it and the next url match.
          count = 2
       }

       if (! (count && count--)) {
          url = "<a " href ">" url "</a>"
       }

       head = head substr(tail,1,RSTART-1) url
       tail = substr(tail,RSTART+RLENGTH)
    }

    print head tail
}

关于regex - sed regex可以模拟后向和前瞻吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14887007/

相关文章:

linux - 如何仅匹配主机文件中的前两个主机

shell - 在函数 awk 中声明的局部变量

linux - 将HDFS Hadoop中的最后5个更新文件复制到bash中的目标文件夹

regex - 字符类\w不工作?

python - 在 Python 中从(字符串)元组写入 csv

javascript - 将 person[0].email 拆分为 ['person' , '0' , 'email' ]

awk - 结合多个awk命令

python - 无法从网页中获取一些分散的项目

bash - sed 删除特定点,包括模式本身

c - 如何在程序输出本身中查看当前进程状态