gpt4 book ai didi

regex - 为什么这个 Regex 匹配只显示捕获变量中的第一个单词,而不是整行?

转载 作者:行者123 更新时间:2023-12-05 09:08:25 25 4
gpt4 key购买 nike

我是 Perl 和正则表达式的新手,所以如果我误用了术语,请耐心等待。

我正在尝试读取包含电影剧本的文本文件,并使用正则表达式显示特定角色所说的所有台词。这是我正在使用的摘录:

BRIAN: Hello, mother.
MANDY: Don't you 'hello mother' me. What are all those people doing out ther e?!
BRIAN: Oh. Well-- well, I, uh--
MANDY: Come on! What have you been up to, my lad?!
BRIAN: Well, uh, I think they must have popped by for something.
MANDY: 'Popped by'?! 'Swarmed by', more like! There's a multitude out there!
BRIAN: Mm, they-- they started following me yesterday.
MANDY: Well, they can stop following you right now. Now, stop following my son! You ought to be ashamed of yourselves.
FOLLOWERS: The Messiah! The Messiah! Show us the Messiah!
MANDY: The who?
FOLLOWERS: The Messiah!
MANDY: Huh, there's no Messiah in here. There's a mess, all right, but no Me ssiah. Now, go away!
FOLLOWERS: The Messiah! The Messiah!
MANDY: Ooooh.
FOLLOWERS: Show us the Messiah! The Messiah! The Messiah! Show us the Messiah!
MANDY: Now, you listen here! He's not the Messiah. He's a very naughty boy! Now, go away!

代码如下:

  1 use strict;
2 use warnings;
3
4 my $filename = "movie_script.txt";
5 my $charname = $ARGV[0];
6
7 if (-e $filename) {
8 print "File exists.\n";
9 } else {
10 print "Alas, file does not exist.\n";
11 exit 1;
12 }
13
14 open(my $fh, '<', $filename);
15
16 my $match = "^($charname):.*/i";
17
18 while (my $line = <$fh>) {
19 if ( $line =~ m/^($charname):.*/i ) {
20 $line =~ s/($charname): //i;
21 print $line;
22 }
23 }
24 print "\n";
25 close $fh;

代码运行良好,当我运行程序时,将“Brian”作为命令行参数传递,它只显示 Brian 的台词,如果我输入“Mandy”或“Followers”(均不区分大小写。 )

我试图了解捕获变量的工作原理,以便我可以更灵敏地操作文本文件。当我将第 21 行更改为 print $1 而不是 print $line 时,我希望结果是相同的,因为我提供的正则表达式应该匹配任何实例“BRIAN”,后跟一个冒号,然后是任意数量的字符,直到行尾。

然而,当我这样做时,它只会返回:

BRIANBRIANBRIANBRIAN

... 而不是属于 Brian 的四行。所以我尝试交换第 22 行和第 21 行,将 print $1 语句放在正则表达式替换之前,但返回相同的结果。

为什么捕获变量只显示第一个单词“BRIAN”而不显示整行?我确信这是一个非常简单的错误,但我很难理解我做错了什么。

最佳答案

让我们看看您的代码:

while (my $line = <$fh>) {
if ( $line =~ m/^($charname):.*/i ) {
$line =~ s/($charname): //i;
print $line;
}
}

在你的第一行:

while (my $line = <$fh>) {

您将 $fh 中的一行读入 $line。没关系。然后我们寻找您的角色名称:

if ( $line =~ m/^($charname):.*/i ) {

您在字符串的开头查找字符名称(这就是 ^ 所做的),后跟一个冒号,然后是任何其他字符。 .* 毫无意义,因为它根本不会改变正则表达式匹配的内容。

但是放在 $charname 两边的括号会做一些有趣的事情。他们捕获与正则表达式的那部分匹配的字符串位并将其存储在 $1 中。现在,老实说,这有点浪费。由于 $charname 是固定字符串,您已经知道 $1 中的内容。它将是“BRIAN”或您要查找的任何角色。

$line =~ s/($charname): //i;
print $line;

然后您编辑 $line 以从行的开头删除字符名称和冒号(和空格)。所以你只是得到所说的线。然后打印出来。

到目前为止一切顺利。您的代码在某些地方有点浪费,但它按照您的想法行事。

然后你改变行:

print $line;

收件人:

print $1;

你会感到困惑:-)

但正如我们已经看到的,捕获括号将在 $1 中存储“BRIAN”。因此,如果您打印 $1,您将看到“BRIAN”。

你问,

Why is the capture variable only showing the first word "BRIAN" and not the whole line?

答案是,因为这是您要求它执行的操作。 $1 将包含捕获括号内的内容。这是 $charname。这是“布莱恩”。正则表达式匹配的其余部分在括号之外,因此它不会以 $1 结尾。

这有意义吗?

关于regex - 为什么这个 Regex 匹配只显示捕获变量中的第一个单词,而不是整行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63491233/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com