【问题标题】:Extracting Substring from String with Multiple Special Characters Using Sed使用 Sed 从具有多个特殊字符的字符串中提取子字符串
【发布时间】:2015-10-22 20:17:06
【问题描述】:

我有一个文本文件,其中一行内容如下:

<div id="page_footer"><div><? print('Any phrase's characters can go here!'); ?></div></div>

我想使用sedawk 来提取上面的单引号之间的子字符串,所以它只是打印...

Any phrase's characters can go here!

我希望像上面那样对短语进行分隔,从单引号开始,到单引号结束,紧接着是括号,然后是分号。以下带有捕获组的 sed 命令似乎对我不起作用。有什么建议吗?

sed '/^<div id="page_footer"><div><? print(\'\(.\+\)\');/ s//\1/p' /home/foobar/testfile.txt

【问题讨论】:

  • 除非您使用 unicode 或其他字符集以使撇号与单引号不完全相同,或者使用其他形式的上下文或锚点,否则这将是模棱两可的。但是,您可以改为在 ('') 序列之间获取文本。很可能,您的 sed 版本与您尝试在那里使用的正则表达式语法实现不同...
  • 是的,使用 ('') 作为锚点就可以了。有关如何使用 sed 或 awk 最好地实施此解决方案的任何建议?

标签: regex bash sed


【解决方案1】:

不正确的是使用 cut like

 grep "page_footer" /home/foobar/testfile.txt | cut -d "'" -f2

字符串中的单引号会出错。首先计算单引号的数量会将其从简单的解决方案变为过于复杂的解决方案。

使用 sed 的解决方案更好:删除第一个单引号之前的所有内容以及最后一个单引号之后的所有内容。当您第一次用单引号关闭 sed 参数,转义单引号并再次打开 sed 字符串时,字符串中的单引号会变得混乱:

grep page_footer /home/foobar/testfile.txt | sed -e 's/[^'\'']*//' -e 's/[^'\'']*$//'

这不是完整的解决方案,您还想删除第一个/最后一个引号:

grep page_footer /home/foobar/testfile.txt | sed -e 's/[^'\'']*'\''//' -e 's/'\''[^'\'']*$//'

将 sed 参数写入双引号字符串并使用 .匹配单引号的通配符会使行更短:

grep page_footer /home/foobar/testfile.txt | sed -e "s/^[^\']*.//" -e "s/.[^\']*$//"

【讨论】:

    【解决方案2】:

    使用高级grep(例如在 Linux 中),这可能就是您要查找的内容

    grep -Po "(?<=').*?(?='\);)"
    

    【讨论】:

    • 我对 Perl 正则表达式不是很熟悉。你能解释一下你的答案吗?似乎它只是使用('') 作为锚点并提取子字符串。是否可以将其扩展为也包含第一个锚左侧的所有文本(&lt;div id="page_footer"&gt;&lt;div&gt;&lt;? print)。谢谢。
    • 我使用类似 Perl 的表达式有两个原因:非贪婪捕获 .*?(以便您可以在同一行中获取多个打印语句)和前瞻/后视 (regular-expressions.info/lookaround.html)。 Lookaheads/lookbehinds 与普通捕获组的不同之处在于它们不捕获(包含在输出中)匹配部分,它们只是看到那些匹配部分存在。
    猜你喜欢
    • 2021-01-21
    • 2017-01-31
    • 2015-02-15
    • 2015-06-07
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-26
    相关资源
    最近更新 更多