sed与括号内的字符不匹配

时间:2015-07-03 12:01:05

标签: regex sed regex-negation

我正在尝试提出一个SED贪婪的表达式,它忽略了html引号中的内容,并且只匹配该元素的文本。

<p alt="100">100</p> #need to match only second 100
<img src="100.jpg">100</img> #need to match only second 100
<span alt="tel:100">100</span> #need to match only second 100

这些是我的尝试:

grep -E '(!?\")100(!?\")' html # this matches string as well as quotes 
grep -E '[^\"]100[^\"]' html # this doesn't work either

修改

确定。我试图简化问题,但也许这是错的。

使用命令sed -r '/?????/__replaced__/g' file我需要看到:

<p alt="100">__replaced__</p>
<img src="100.jpg">__replaced__</img> 
<span alt="tel:100">__replaced__</span> 

4 个答案:

答案 0 :(得分:4)

我不认为使用sed(或grep)处理HTML是一个好主意。考虑使用python,它的标准库中有HTML push parser。这使得从数据中分离标签变得容易。由于您只想处理标记之间的数据,因此它看起来像这样:

#!/usr/bin/python

from HTMLParser import HTMLParser
from sys import argv

class MyParser(HTMLParser):
    def handle_data(self, data):
        # data is the string between tags. You can do anything you like with it.
        # For a simple example:
        if data == "100":
            print data

# First command line argument is the HTML file to handle.
with open(argv[1], "r") as f:
    MyParser().feed(f.read())

更新更新的问题:要使用此功能编辑HTML,您必须实施handle_starttaghandle_endtag方法以及handle_data以重新打印已解析标签的方式。例如:

#!/usr/bin/python

from HTMLParser import HTMLParser
from sys import stdout, argv
import re

class MyParser(HTMLParser):
    def handle_starttag(self, tag, attrs):
        stdout.write("<" + tag)
        for k, v in attrs:
            stdout.write(' {}="{}"'.format(k, v))
        stdout.write(">")

    def handle_endtag(self, tag):
        stdout.write("</{}>".format(tag))

    def handle_data(self, data):
        data = re.sub("100", "__replaced__", data)
        stdout.write(data)

with open(argv[1], "r") as f:
    MyParser().feed(f.read())

答案 1 :(得分:2)

第一个警告是HTML不是用正则表达式解析的好主意 - 一般来说 - 使用HTML解析器就是答案。大多数脚本语言(perlpython等)都有HTML解析器。

请参阅此处,了解原因:RegEx match open tags except XHTML self-contained tags

如果你真的必须:

/(?!\>)([^<>]+)(?=\<)/

DEMO

答案 2 :(得分:1)

您可以尝试下面的PCRE正则表达式。

grep -oP '"[^"]*100[^"]*"(*SKIP)(*F)|\b100\b' file

grep -oP '"[^"]*"(*SKIP)(*F)|\b100\b' file

这将匹配双引号内不存在的数字100。

DEMO

答案 3 :(得分:0)

你的问题因为它的演变而变得有点混乱,但这是你要求的吗?

$ sed -r 's/>[^<]+</>__replaced__</' file
<p alt="100">__replaced__</p> #need to match only second 100
<img src="100.jpg">__replaced__</img> #need to match only second 100
<span alt="tel:100">__replaced__</span> #need to match only second 100

如果没有,请清理您的问题,只显示最新的样本输入和预期的输出和解释。