对于字符串:
text::handle:e@ma.il::text
text::chat_identifier:chat0123456789&text
我有当前的正则表达式:
m/(handle:|chat_identifier:)(.+?)(:{2}|&)/
我目前正在使用$2
来获取我想要的值(在第一个字符串e@ma.il
中,在第二个字符串chat0123456789
中)。
是否有更好/更快/更简单的方法来解决这个问题?
答案 0 :(得分:4)
它是否“更好”取决于上下文,但您可以采用这种方法:将字符串拆分为“:”并获取结果列表的第四个元素。如果第三个字段可以是“handle”或“chat_identifier”以外的其他字段,则可以说比正则表达式更具可读性,更强大。
我认为这两种方法的速度都非常相似,但几乎可以用于perl中的任何实现。我想表明速度对于这个步骤至关重要,然后再担心它......
答案 1 :(得分:2)
对于正则表达式解决方案,这个解决方案稍微简单,不需要回溯:
m/(handle|chat_identifier):([^:&]+)/
注意略有不同:你的允许单个冒号在值内,我的不允许(它在遇到的第一个冒号时停止)。如果这不是问题,您可以使用我的变体。或者正如我在评论中提到的那样,在:
处拆分并使用结果中的第四个元素。
只停留在双冒号的等效版本是:
m/(handle|chat_identifier):((?:(?!::|&).)+)/
不是那么漂亮,但它仍然避免回溯(前瞻可能会让它变慢,但是......如果速度很重要,你需要对其进行分析。)
答案 2 :(得分:1)
看起来你已经有了很多好的解决方案。拆分方法看起来最简单。但是根据您的要求,您还可以使用更通用的正则表达式来打破其基本部分中的字符串。它适用于其他数据类型和属性名称,而不是示例。
([^:]+)::([^:]+):([^:&]+)(?:::|&)\1
捕获组如下:
答案 3 :(得分:1)
如果您想要的值始终位于同一位置,并且可以安全地拆分:
和&
,那么以下内容可能适用于您:
use Modern::Perl;
say +( split /[:&]+/ )[2] for <DATA>;
__DATA__
text::handle:e@ma.il::text
text::chat_identifier:chat0123456789&text
输出:
e@ma.il
chat0123456789