我正在尝试使用正则表达式从PDF中提取一些自定义属性(我将使用grep)。
PDF自定义属性是以以下格式存储的键值:
<</key1(value1)/key2(value2)/key3(value3)>>
内部值的括号被转义:
/key4(outside \(inside\) outside)
我执行了以下正则表达式来提取键的值:
grep -Po '(?<=key4\().*?(?=\))' "sample.txt"
但是,将其应用于key4(带有括号)时,会产生:
outside \(inside\
因为它停在第一个)
(已转义的那个)中,而不是未转义的那个。
如何在正则表达式中忽略转义的括号?
谢谢。
PD:我愿意接受sed或awk中的建议。
答案 0 :(得分:1)
您可以这样做
(?<=key4\()[^\\()]*(?:\\[\S\s][^\\()]*)*(?=\))
https://regex101.com/r/B4qKdh/1
展开:
(?<= key4\( )
[^\\()]*
(?: \\ [\S\s] [^\\()]* )*
(?= \) )
答案 1 :(得分:1)
您可以使用类似{p>的sed
解决方案
sed 's/.*key4(\([^\()]*\(\\.[^\()]*\)*\)).*/\1/'
sed -E 's/.*key4\(([^\()]*(\\.[^\()]*)*)\).*/\1/'
请参见online sed
demo。
POSIX ERE模式详细信息
.*
-任意0个以上的字符key4\(
-key(
文字字符串\( - a
(`char ([^\()]*(\\.[^\()]*)*)
-第1组:
[^\()]*
-除\
,(
和)
以外的0个或更多字符(\\.[^\()]*)*
-重复0次或更多次
\\.
-一个\
后跟任意1个字符[^\()]*
-除\
,(
和)
以外的0个或更多字符\)
-一个)
字符.*
-任意0个以上的字符请注意,POSIX BRE模式仅交换了文字和捕获括号(转义了捕获括号(POSIX BRE中的(
与文本(
字符匹配,它不是捕获组的开始)。
替换部分中的\1
是第1组占位符,并用该组值替换整个匹配项。
答案 2 :(得分:0)
在任何UNIX盒子上的任何外壳中都有任何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的匹配项,然后在打印之前将替换字符串放回其原始值。