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