如何使用Perl将冒号放在一个从末尾算起两个字符的字符串中?

如何使用Perl将冒号放在一个从末尾算起两个字符的字符串中?,perl,string,Perl,String,我正在试图找到一种方法,将冒号(:)放入字符串中,从字符串末尾起两个字符 $meetdays示例: 1200=>12:00900=>9:001340=>13:40 不确定这是正则表达式还是我不知道的另一个函数。您可以尝试以下方法: s/..$/:$&/ 它匹配字符串末尾的两个字符,并将其替换为冒号和匹配的字符串(即两个字符) 编辑 修复了sed backref与perl等效的问题 s/(?=..$)/:/ 不要使用roe建议的$&。perldoc perlvar: 在程序中的任何位置

我正在试图找到一种方法,将冒号(:)放入字符串中,从字符串末尾起两个字符

$meetdays示例:
1200=>12:00
900=>9:00
1340=>13:40

不确定这是正则表达式还是我不知道的另一个函数。

您可以尝试以下方法:

s/..$/:$&/
它匹配字符串末尾的两个字符,并将其替换为冒号和匹配的字符串(即两个字符)

编辑
修复了sed backref与perl等效的问题

s/(?=..$)/:/
不要使用roe建议的
$&
。perldoc perlvar:

在程序中的任何位置使用此变量都会对所有正则表达式匹配造成相当大的性能损失。请参阅“BUGS”


sed的Perl等价物是$&,因此它应该是:

 $s = s /..$/:$&/s;
roe的答案是“可行的”,但它的正则表达式相当不可信

我会为你付出更多

s/(^.*)(..$)/$1:$2/
因为我只是喜欢反手

对你所做的事情来说,这太过分了,但对我来说,这在语义上更具表现力

也可以使用

my $string = "1200";
substr $string, -2, 0, ':';

# $string => '12:00';

和往常一样,有不止一种方法。有一个性能惩罚是的,但这是我想到的第一个模式(是的,我最初是一个sed人),在这种情况下,它可能足够快了,你不认为吗?:)速度够快的。。这是一个非常小的脚本无论如何。。。艾尔尼厄的解决方案奏效了,关键不在于它是否快。关键是新手首先不应该养成使用$的习惯。当普通的s/(..)$/:$1/可以正常工作时,包括在旧版本的Perl中(甚至在许多非Perl正则表达式实现中),为什么要使用花哨的“零宽度正向前瞻”操作符(?=)哪里?=不起作用?我认为非Perl正则表达式实现会带来痛苦;我不会因为期待他们而伤害自己。要找到一个不支持零宽度lookaheads的perl,你得追溯到十年前。好吧,这并不是最优化的表达式,但它很容易理解,而且很有技巧,这怎么会毫无帮助(如downvote)?向上投票不是更好的答案吗?引用perlvar的话:“在程序中的任何地方使用这个变量都会对所有正则表达式匹配造成相当大的性能损失。”。不要使用$&!说真的,你们听说过“先解决,后优化”吗?如果出现性能问题的话?我已经承认它不是最优化的(你会停止把它打到地上吗?),roe:perl文档说永远不要使用它,因为所有包含的文件中的所有正则表达式都会对性能造成重大影响。看到正则表达式在任何地方都被使用,我认为不让它在任何地方同时变慢是公平的,因为有一种更简单的方法来解决问题而不受惩罚。我认为substr()明显更快,更容易阅读,更直观。只有当你不太了解正则表达式时才更直观。这个看起来很直观。。。不知道为什么,但它在csv文件中创建了20行,然后转储并给我这个错误。。。substr位于/test3第237行的字符串外部。-我最好的猜测是它遇到了一个值0,这发生在我的数据中,不是坏数据,只是意味着一个diff事件“substr out of string”错误意味着CSV中的数据宽度小于2个字符。因此,它不能从末尾插入“:”两个字符(-2)。如果您有“diff event”,那么您需要相应地过滤substr或regex的使用。第一次捕获有点浪费,为什么不简单地使用s/(..$)/:$1/?尽管第一部分确实是冗余的,但可读性要高得多。(至少是我解析正则表达式的方式)+1 blixtor@肯特:虽然在这种情况下没有实际的区别,但您的原始答案要慢一些,因为Perl需要回溯两个字符以匹配最后的“.”。如果“.”是一个更复杂的表达式,那么开头的“*”很容易使它慢得多。