gsub:删除直到第一次出现而不是一行中给定字符的最后一次出现

gsub: remove till first occurence instead of last occurence of a given character in a line

我有一个 html 文件,我基本上尝试使用 sub/gsub 功能删除 <...> 的第一次出现。

我使用 awk regex . * + 来匹配 < > 之间的任何内容。但是 > 的第一次出现正在被转义(?)。不知道有没有办法解决。

sample input file.txt (x添加不打印空):

<div>fruit</div></td>x
<span>banana</span>x
<br/>apple</td>x

代码:

awk '{gsub(/^<.*>/,""); print}' file.txt

当前输出:

x
x
x

期望输出:

fruit</div></td>x
banana</span>x
apple</td>x

使用您显示的示例,请尝试以下 awk 代码。简单的解释是,使用 awk 编程的 sub 替代函数。然后替换开始 < 直到(使用 [^>] 意味着直到 > 第一次出现) > including > with NULL in current line, finally print edited/non-edited 行 1.

awk '{sub(/^<[^>]*>/,"")} 1' Input_file


第二个解决方案: 使用 awkmatch 函数匹配第一次出现的值 < 直到第一次出现 > 并打印剩余的行。

awk 'match([=11=],/^<[^>]*>/){print substr([=11=],RSTART+RLENGTH)}' Input_file

OR 如果您有不是从 < 开始的行并且您还想打印它们然后使用以下:

awk 'match([=12=],/^<[^>]*>/){print substr([=12=],RSTART+RLENGTH);next} 1' Input_file

然而第一​​次出现的>被转义了(?)。

不,你得到的结果与 GNU AWK 中的结果一样 manual

awk(...)regular expressions always match the leftmost, longest sequence of input characters that can match

这在其他语言的正则表达式用法中称为greedy,所以说for

<div>fruit</div></td>x

/^<.*>/ 确实匹配

<div>fruit</div></td>

因此你以 x 结束。在支持所谓的非贪婪匹配的语言中,您可以在这种情况下利用它,例如在 ECMAScript

let str = "<div>fruit</div></td>x";
let out_str = str.replace(/^<.*?>/, "");
console.log(out_str);

输出

fruit</div></td>x

正如 GNU AWK 手册在 GNU AWK 中所说的,它总是最长的(贪婪的),因此你必须使用 [^>] 除了 > 以防止匹配跨越从第一个 < 到最后一个 >,其中将包含 > inside.