鉴于下面的示例字符串,我 try catch “收件人”、“发件人”、“主题”和“类型”字段,并以不同的格式将它们吐出。问题是这些字段(收件人、发件人等)可以按任何顺序排列。
正则表达式的示例字符串
<cfmail to="#toAddr#" from="#fromAddress"
subject="#subject#" type="html">
#emailMsg#
</cfmail>
我正在寻找的输出
to:toAddr, from:fromAddress, subject:subject
如果我知道我感兴趣的那些字段的顺序始终相同,那么这很容易,但是我很难知道如何进行此匹配,例如,如果“from”出现在“to”之前'
我现在拥有的 Perl 一行是(只是用“to”和“subject”进行测试)
s/<cfmail.*?((to)="(.*?)")|((subject)="(.*?)").*<\/cfmail>/\1:\2, \3:\4/g
这最终与“to”值匹配,但停在那里,我没有得到任何“subject”值。我已经尝试了几种变体,其中我更改了匹配组设置等,但没有成功。
最佳答案
您是否需要允许缺少字段(例如没有 type
字段)?除了这四个领域之外,其他领域呢?如果您对这两个问题的回答都是“否”,则此正则表达式应该可以解决问题:
s!<cfmail(?:\s+to="(?<to>[^"]+)"|\s+from="(?<from>[^"]+)"|\s+subject="(?<subject>[^"]+)"|\s+type="(?<type>[^"]+)")+>.*?</cfmail>!to:$+{to}, from:$+{from}, subject:$+{subject}!gs
这是更易读的正则表达式:
<cfmail
(?:
\s+to="(?<to>[^"]+)"
|
\s+from="(?<from>[^"]+)"
|
\s+subject="(?<subject>[^"]+)"
|
\s+type="(?<type>[^"]+)"
)+
>
.*?</cfmail>
...以及 DEMO
你们实际上已经很接近了;交替是关键。您只需要添加一个量词。
请注意,我从字段名称中删除了捕获组。您已经知道这些名称,只需将它们与正确的值配对即可。命名组使这变得更加容易。
关于正则表达式以任意顺序匹配多个捕获组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32876469/