gpt4 book ai didi

regex - 如何在正则表达式中定义空格(在 awk 中)?

转载 作者:行者123 更新时间:2023-12-01 19:46:23 28 4
gpt4 key购买 nike

我想打印""内的文本。例如我有以下字符串:

gfdg "jkfgh" "jkfd fdgj fd-" ghjhgj
gfggf "kfdjfdgfhbg" "fhfghg" jhgj
jhfjhg "dfgdf" fgf
fgfdg "dfj jfdg jhfgjd" "hfgdh jfdhgd jkfghfd" hgjghj

我只想打印以下内容:

"jkfgh" "jkfd fdgj fd-"
"kfdjfdgfhbg" "fhfghg"
"dfgdf"
"dfj jfdg jhfgjd" "hfgdh jfdhgd jkfghfd"

我尝试使用 awk 使用以下正则表达式:

awk '{for(i = 1; i <= NF; i++) if($i ~ /^\"[A-Za-z.$]*([A-Za-z.$][[:space:]]*[A-Za-z.$])*\"$/) print $i}' sample.txt

但它会打印空格之前的所有内容,并且实际上无法识别我在正则表达式中定义的空格。我当前的输出是:

"jkfgh"
"kfdjfdgfhbg" "fhfghg"
"dfgdf"
"dfj

如您所见,只有没有任何空格的内容才能正确打印。

我也尝试过 [[:blank:]]\t 以及 ' ' 但没有成功。

如果有人能告诉我如何更改此正则表达式并包含空格,我将不胜感激。

最佳答案

该问题的标题具有误导性,并且基于对 awk 的根本误解。 .

天真的答案是awk 的正则表达式中,空格可以简单地表示为它本身(文字)。
更一般地,您可以使用 [[:space:]]匹配空格、制表符或换行符(GNU Awk 还支持 \s )和 [[:blank:]]匹配空格或制表符。

但是,问题的关键在于,默认情况下,Awk 将每个输入行按空格分割为多个字段,因此,根据定义,输入字段本身不包含空格,因此任何匹配字段值中空格的尝试都将不可避免地失败。

手头的输入包含未加引号和带引号的字符串混合的字段,但 POSIX Awk 不支持将带引号的字符串识别为字段

@fedorqui has made a valiant attempt通过用双引号将输入拆分为字段来解决该问题,但它不能替代对带引号的字符串的正确识别,因为它不会保留真实的字段边界。

如果您有GNU Awk,您可以使用特殊的 FPAT 近似识别带引号的字符串变量,它不是定义一个分隔符来分割行,而是允许定义一个描述字段的正则表达式(并忽略未识别的标记):

re='[[:alpha:]][[:alpha:] ]*[[:alpha:]]' # aux. shell variable
gawk -v FPAT="\"$re\"|'$re'" '{
for(i=1;i<=NF;++i) printf "%s%s", $i, (i==NF ? "\n" : " ")
}' sample.txt

适用于单引号和双引号字符串

说明:

  • FPAT="\"$re\"|'$re'"将字段定义为仅由字母和空格组成的双引号或单引号字符串,两端至少有一个字母(如OP代码中所示)。
  • 请注意,这会自动排除每个输入行上未加引号的标记 - 它们将不会反射(reflect)在 $1 中,...和NF .
  • 因此,循环 for(i=1;i<=NF;++i)已限制为仅枚举匹配字段。
<小时/>

请注意,通常,在这种情况中对带引号的字符串内容的限制幸运地绕过了这种方法固有的限制,即无法处理转义的嵌套引号(相同类型)。

如果此限制可以接受,您可以使用以下习惯用法对裸字(不带引号的标记)和带引号的字符串混合的输入进行标记化:

gawk -v "FPAT=[^[:blank:]]+|\"[^\"]*\"|'[^']*'" ...

关于regex - 如何在正则表达式中定义空格(在 awk 中)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29512854/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com