我正在尝试使用正则表达式从PDF中提取一些自定义属性(我将使用grep)。
PDF 自定义属性是按以下格式存储的键值:
<</key1(value1)/key2(value2)/key3(value3)>>
值内的括号被转义:
/key4(outside (inside) outside)
我做了以下正则表达式来提取键的值:
grep -Po '(?<=key4().*?(?=))' "sample.txt"
但是,当将其应用于 key4(带括号)时,它会产生:
outside (inside
因为它在第一个)
(被转义的那个)中停止,而不是在未转义
的那个中停止。如何在正则表达式中忽略转义的括号?
提前谢谢你。
PD:我愿意接受 sed 或 awk 的建议。
你可以这样做
(?<=key4()[^\()]*(?:\[Ss][^\()]*)*(?=))
https://regex101.com/r/B4qKdh/1
扩大:
(?<= key4( )
[^\()]*
(?: \ [Ss] [^\()]* )*
(?= ) )
您可以使用sed
解决方案,例如
sed 's/.*key4(([^()]*(\.[^()]*)*)).*/1/'
sed -E 's/.*key4(([^()]*(\.[^()]*)*)).*/1/'
请参阅在线sed
演示。
POSIX ERE 模式详细信息
.*
- 任何 0+ 字符key4(
-key(
文字字符串( - a
(' 字符([^()]*(\.[^()]*)*)
- 第 1 组:[^()]*
- 除、
(
和)
以外的 0 个或多个字符(\.[^()]*)*
- 0 次或多次重复\.
- 后跟任意 1 个字符的[^()]*
- 除、
(
和)
以外的 0 个或多个字符
)
-)
炭.*
- 任何 0+ 字符
请注意,POSIX BRE 模式只是将文字和捕获括号转义交换(POSIX BRE 中的(
匹配文字(
字符,它不是捕获组的开始)。
替换部件中的1
是组 1 占位符,并将整个匹配项替换为该组值。
在任何 UNIX 机器上的任何 shell 中使用任何 awk:
$ awk '
{ gsub(/\[(]/,"n1"); gsub(/\)/,"n2") }
match($0,/[/]key4[(][^)]+/) {
$0 = substr($0,RSTART+6,RLENGTH-6)
gsub(/n1/,"\("); gsub(/n2/,"\)")
print
}
' file
outside (inside) outside
使用 GNU awk 用于第三个参数匹配():
$ awk '
{ gsub(/\[(]/,"n1"); gsub(/\)/,"n2") }
match($0,/[/]key4[(]([^)]+)/,a) {
$0 = a[1]
gsub(/n1/,"\("); gsub(/n2/,"\)")
print
}
' file
outside (inside) outside
以上只是将(
和)
替换为包含换行符的字符串(换行符分隔的记录不能存在于换行符中)n1
并n2
,然后找到 key4 的匹配项,然后将替换字符串放回其原始值打印前。