如何使用Perl剪切字符串的一部分?

时间:2015-08-12 15:37:38

标签: perl

我需要从字符串中间切出一些字符;要剪切的字符序列的起始位置和结束位置会有所不同。

例如,假设我有句子

  

快速的棕色狐狸跳过懒狗

我需要从第一个角色向前计数,直到我到达fox,将f的角色位置分配给变量,继续向前计数直到我到达'&#39 39;然后剪切出初始f和最终e之间的字符。

注意

e中的jumped位于foxthe之间,应该忽略它,它必须找到e的位置the

2 个答案:

答案 0 :(得分:4)

要删除字符串中您不确定所有插入字符的部分,可以使用substitution operator。如果匹配,则匹配开头的位置(零索引)存储在$-[0](如果$LAST_MATCH_START[0],则为use English;):

use strict;
use warnings;
use 5.010;

my $string = 'The quick brown fox jumped over the lazy dog';
$string =~ s/fox.*the//;

say "Matched at char $-[0]" if defined $-[0];
say "New string: $string";

输出:

Matched at char 16
New string: The quick brown  lazy dog

""?

请注意,我使用的正则表达式是贪婪的,所以它会每隔the吞噬一次,直到最后一次。对于字符串:

The quick brown fox jumped over the lazy dog and the sleepy cat

你会得到:

Matched at char 16
New string: The quick brown  sleepy cat

要在第一次出现the时停止,请将替换更改为:

s/fox.*?the//;

仅限整个单词

上面的两个正则表达式仍将匹配部分单词。字符串:

The quick brown foxhole jumped over their lazy dog

给出:

Matched at char 16
New string: The quick brown ir lazy dog

仅匹配整个单词*将替换更改为:

s/(?:^|\s+)\Kfox\s+.*\s+the(?=\s+|\z)//; # greedy

s/(?:^|\s+)\Kfox\s+.*?\s+the(?=\s+|\z)//; # non-greedy

*很难定义英语句子中整个单词的含义。上面要求一个单词在两侧被一个或多个空格包围,或者位于字符串的开头或结尾,这排除了in-the-know之类的内容,但也排除了"fox"和{{1 }}。这显然不是一个很好的定义。

答案 1 :(得分:2)

  

我有句子

     
    

快速的棕色狐狸跳过懒狗

  
     

我需要从第一个角色向前计数,直到我到达'狐狸',将'f'的角色位置变为变量,继续向前计数,直到我到达''然后切出角色,包括以及'f'和'e'之间。

我引用了你的问题描述,因为它表明了你接近Perl的C心态。在比C更高的水平,你的问题是实际上切掉“棕色”和“懒惰”之间的单词。 Perl允许您直接表达这个想法:

 $ perl -wE 'say join(" ", (split /\s+(?:fox|the)\s+/, "The quick brown fox jumped over the lazy dog")[0, 2])'
The quick brown lazy dog

或者,使用范围运算符:

$ perl -wE 'say join " ", grep !(/^fox$/ .. /^the$/), split " ", "The quick brown fox jumped over the lazy dog"'
The quick brown lazy dog

字面意思是“在'fox'和'the'之间取出所有单词 not ,使用单个空格作为单词分隔符将它们连接在一起,然后打印生成的句子。”

如果原始句子有很多多个字,第一个字可能更有效率,因为它只会创建一个三元素列表。

您可以在perldoc perlop中详细了解range operator。由于您刚刚开始学习Perl,您应该至少阅读一次perldoc perltoc中提到的所有内容,包括所有常见问题解答部分。