我需要从字符串中间切出一些字符;要剪切的字符序列的起始位置和结束位置会有所不同。
例如,假设我有句子
快速的棕色狐狸跳过懒狗
我需要从第一个角色向前计数,直到我到达fox
,将f
的角色位置分配给变量,继续向前计数直到我到达'&#39 39;然后剪切出初始f
和最终e
之间的字符。
e
中的jumped
位于fox
和the
之间,应该忽略它,它必须找到e
的位置the
。
答案 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
中提到的所有内容,包括所有常见问题解答部分。