使用正则 pcregrep,sed, awk等工具(详解)实现网页源码指定内容提取

in Linux with 0 comment

先来了解 pcregrep 对比于 grep,来自 chatGPT

pcregrep 是一个强大的命令行工具,它使用 Perl 兼容的正则表达式 (PCRE) 来搜索文本。与标准的 grep 命令相比,pcregrep 提供了更多的正则表达式特性,允许用户执行更复杂和更灵活的文本匹配操作。这些特性包括但不限于更复杂的字符类、回溯引用、命名捕获组以及前后查找等。

-M 参数

-M--multiline 参数允许 pcregrep 在多行模式下进行模式匹配。这意味着你可以使用一个正则表达式匹配跨越多行的模式。在不使用 -M 参数的情况下,pcregrep(以及标准的 grep)通常在单行模式下工作,每次只考虑输入中的一行。-M 参数允许正则表达式模式匹配操作涵盖输入中的连续多行,这在需要匹配或搜索跨多行展开的文本段落时非常有用。

pcregrepgrep 的区别

尽管 pcregrep 和标准的 grep 在很多基本用途上相似,主要区别在于它们支持的正则表达式的类型和复杂性:

总之,尽管 pcregrep 在某些情况下提供了比标准 grep 更强大的功能,但它也可能需要用户对 Perl 兼容的正则表达式有更深入的了解。在选择使用哪个工具时,需要根据特定任务的需求和复杂性来决定。

使用 pcregrep 把file文件中的描文本提取出来存入到 newfile 文件中

pcregrep -M '(?s)<a .*?>(.*?)<\/a>' file >> newfile

pcregrep -M 表示对多行进行操作,(?s) 这是一个内联修饰符,它将正则表达式的模式设置为“单行模式”。在单行模式中,.(点)匹配任何字符,包括换行符。这意味着正则表达式可以匹配跨越多行的模式。

<a .*?> 匹配开始的 标签。<a 是标签的开始,.*? 是一个非贪婪匹配,它匹配尽可能少的任何字符直到遇到 >,确保只匹配到单个 标签的开头部分。

(.*?) 这是一个非贪婪的捕获组,用于匹配 标签内的任意文本,直到遇到第一个 结束标签。

<\/a> 匹配结束的 标签。/ 是转义的 /,因为在正则表达式中 / 通常用作分隔符。

把每行开始的空白字符去掉(空格,tab,换行)

sed -i 's/^\s\+//g' newfile

这里^ 表示行首, \s 表示空白字符(空格,tab,换行)+表示重复1次或多次空白字符, //表示替换为空,而后是 g 表示全局操作

删除每行的换行,除了后边的换行外

awk '/<\/a>$/ {print; next} {printf "%s", $0}' newfile > newfile2

这里源文件内容中,有的行中xxx是在一行,有的分成了三行,因此要处理成单行,因为 sed 是针对单行处理文本的。

这条 awk 命令检查 newfile 文件中的每一行,对于以 结尾的行,它将它们原样打印到 newfile2 文件中,并为每个这样的行添加换行符。对于其他行,它将它们连续输出到一行中,直到遇到一个以 结尾的行为止。

其中 / 同样表示分割字符, <\/a>$ 表示正则,匹配以结尾的行,接着的 {print; next} 表示对正则匹配到的内容执行的操作,print; next 这里表示打印(print)当前行(因为不需要处理),而后直接跳到下一行执行操作(next), 接着的
{printf "%s", $0} 表示没有匹配到正则后的动作,printf 打印当前行 $0, 直接拼接到上一行尾,而不添加其它操作。
因此如果多行都不是以结尾的话,它们会拼到一起,当然也可以添加一个空格进行分割,用 "%s " 即可。

提取锚文本部分存入到 newfile2

sed -i 's|<a [^>]*>\(.*\)</a>|\1|g' newfile2

这条 sed 命令设计用于在文本文件中查找和处理 HTML 标签,具体是删除这些标签本身,只保留标签内的文本内容。s 表示替换操作,注意这里使用|作为分隔符,一般是使用 /,但是如果要处理的字符串中有 / 这样的字符串,就要重新换一个。

<a [^>]*>这里表示匹配 <a 一个空格,然后是[]字符组,字符组中的^表示非的意思,而不是开始的意思,即表示不是以>结尾的字符串,而后是 * 表示重复0或多次,然后是>, 因此这里表示<a ...> 表示<a> 之间所有字符。而后是捕获组
.*表示任意字符, sed 中捕获组要使用 \(\) 界定,接着又是| 分割符号,然后是 \1 表示引用的捕获组中的内容,即.* 表示的锚文本,整体来看 |\a|g 表示将匹配到的内容使用捕获组中的内容替换(全局模式)

去除文本中包含的等标签

sed -i 's/<strong>//g; s/<\/strong>//g' newfile2

这里不用过多解释 //即替换为空 g参数表示全局,即把行内所有 strong 标签都替换, ; 分号用来分割另一条命令,替换的时候/要使用\转义下,即</strong>

去除每行行尾的空格

sed -i 's/[ \t]*$//' newfile2

-i 表示直接修改原文件, s 表示执行替换操作, []表示字符类,其中任意一个都会匹配 [ \t] 表示匹配空格或制表符, *表示0次或多次,$表示行尾 ,//表示替换为空字符, 如果 /t/则表示替换为字符 t

去除不包含任何字符或只包含空格的行

sed '/^ *$/d' newfile2 > file

这里 ^表示行的开始,然后是一个空格,后边的*表示空格重复0次或多次,然后是$表示行结束 /^ *$/ 为正则表达式,后边的d 表示删除命令

注意 sed 是按行处理的,如果是多行,则 sed 就无能为力了

评论已关闭.