正则表达式 - 可选字符序列中的捕获组
我有一个文件,里面有一些我需要从类似JSON的语法中提取的行。我的正则表达式在大多数情况下都能很好地工作,它把我想要的内容提取到第二个捕获组中。但是我注意到,有时候我想要的文本可能会被一些标签包裹起来,而我想忽略这些标签。
示例文件:
{"title_available" "text1"}
{"title_value" "<c(20a601)>text2"}
{"tags"
{"all" "text3"}
{"ignore" "text4"}
{"chargeFactor" "text5 %1%"}
{"resourceSpeed" "%1% text6"}
}
{"rules" "bla-bla-bla\n\n \"BLA\" bla-bla-bla."}
{"id1" "<c(c3baae)>text7</c>"}
我的正则表达式:
\s+{\"\S+\" \"(<c\(\S+\)>)?(.+)\"}
期望的输出:
text1
text2
text3
text4
text5 %1%
%1% text6
bla-bla-bla\n\n \"BLA\" bla-bla-bla.
text7
当前输出:
all ok except:
text7</c>
我想我需要在第二个捕获组中使用某种前瞻,但我不知道怎么做。另外,我也不确定是否应该为跳过第一个可选的<c...>使用捕获组。有人能帮帮我吗?
附注:模式的速度或简单性并不重要。
2 个回答
2
匹配下面这个正则表达式可以对你所有的例子产生想要的结果。(注意,这里没有使用捕获组。)不过因为你没有说明具体的要求,所以我不确定它对其他字符串是否也适用。
(?:\\\"|[^<>\"])+(?=(?:<[^>]*>)?\"})
这个表达式可以分解成以下几个部分。
(?: # begin a non-capture group
\\\" # match '\' followed by '"'
| # or
[^<>\"] # match a character other than '<', '>' and '"'
)+ # end non-capture group and execute it >= 1 times
(?= # begin a positive lookahead
(?: # begin a non-capture group
< # match '<'
[^>]* # match >= 0 characters other than '>'
> # match '<'
)? # end non-capture group and make it optional
\"} # match '"}'
) # end positive lookahead
2
看起来你的正则表达式没有把结束标签 </c>
从第三个捕获组中排除。要解决这个问题,你可以调整你的正则表达式,让它在有结束标签的情况下把它排除掉。
比如:
\s+{"\S+" "(?:<c\S+>)?(.+?)(?:<\/c>)?"}