4

对于字符串:

  • text::handle:e@ma.il::text
  • text::chat_identifier:chat0123456789&text

我有当前的正则表达式:

m/(handle:|chat_identifier:)(.+?)(:{2}|&)/

我目前正在使用$2以获得我希望的值(在第一个字符串e@ma.il和第二个字符串中chat0123456789)。

不过,有没有更好/更快/更简单的方法来解决这个问题?

4

4 回答 4

4

它是否“更好”取决于上下文,但您可以采用这种方法:将字符串拆分为“:”并获取结果列表的第四个元素。如果第三个字段可以是“handle”或“chat_identifier”以外的内容,那么这可以说比正则表达式更具可读性并且更健壮。

我认为这两种方法的速度都非常相似,但可能几乎适用于 perl 中的任何实现。在担心它之前,我想表明速度对于这一步至关重要......

于 2012-11-22T00:02:29.680 回答
2

对于正则表达式解决方案,这个稍微简单一些,不需要回溯:

m/(handle|chat_identifier):([^:&]+)/

请注意细微的差别:您的值允许单个冒号,而我的不允许(它在遇到的第一个冒号处停止)。如果这不是问题,您可以使用我的变体。或者正如我在评论中提到的那样,拆分为:并使用结果中的第四个元素。

仅在双冒号处停止的等效版本是:

m/(handle|chat_identifier):((?:(?!::|&).)+)/

不是那么漂亮,但它仍然避免了回溯(不过,前瞻可能会使它变慢......如果速度很重要,您将需要对其进行分析)。

于 2012-11-22T00:04:08.730 回答
1

看起来您已经在这里分配了很多好的解决方案。split 方法似乎是最简单的。但是根据您的要求,您还可以使用更通用的正则表达式来破坏其基本部分的字符串。它适用于您的示例之外的其他数据类型和属性名称。

 ([^:]+)::([^:]+):([^:&]+)(?:::|&)\1

捕获组如下:

  • 第 1 组:数据类型。(您的示例中的关键字“文本”。)
  • 第 2 组:属性名称。(示例中的关键字“handle”和“chat_identifier”。)
  • 第 3 组:属性值。
于 2012-11-22T00:27:32.553 回答
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
于 2012-11-22T02:00:46.810 回答