【问题标题】:extracting paragraphs from text with perl用perl从文本中提取段落
【发布时间】:2016-04-04 00:59:42
【问题描述】:

我想从从数据库中检索到的文本变量中提取段落。

为了从文件处理程序中提取 pargaphs,我使用以下代码:

local $/ = undef;
@paragarphs =<STDIN> 

使用 perl 从文本变量中提取段落的最佳选择是什么,以及 cpan 上是否有执行此类任务的模块?

【问题讨论】:

  • 您已更改代码以反映我的回答。这会让阅读这篇文章的其他人感到困惑。请回滚。
  • 是的,我改了,但我的意思是本地 $/=""
  • 将 $/ 设置为您所称的段落分隔符
  • $ perl -ane 'BEGIN { $/="";} { chomp;推@paras,$_; } END { 推@paras, "";打印加入 "\n\n", @paras; }' 文件

标签: perl


【解决方案1】:

你快到了。将$/ 设置为undef 将一口气读入整个文本。

你想要的是local $/ = ""; 来启用段落模式,就像perldoc perlvar 一样(强调我自己的):

$/

输入记录分隔符,默认换行。这会影响 Perl 的 什么是“线”的概念。像 awk 的 RS 变量一样工作,包括 如果设置为空字符串(一个 空行不能包含任何空格或制表符)。您可以将其设置为 多字符字符串以匹配多字符终止符,或 undef 读取文件末尾。将其设置为“\n\n”意味着 与设置为 "" 稍有不同的东西,如果文件包含 连续的空行。 设置为“”将处理两个或更多 连续的空行作为一个空行。设置为“\n\n” 会盲目假设下一个输入字符属于下一个 段落,即使是换行符。


当然,可以从字符串而不是文件中读取文件句柄:

use strict;
use warnings;
use autodie;

my $text = <<TEXT;
This is a paragraph.

Here's another one that 
spans over multiple lines.

Last paragraph
TEXT

local $/ = "";
open my $fh, '<', \$text;

while ( <$fh> ) {

    print "New Paragraph: $_";
}

close $fh;

输出

New Paragraph: This is a paragraph.

New Paragraph: Here's another one that
spans over multiple lines.

New Paragraph: Last paragraph

【讨论】:

  • 好吧,例如,我如何从这个变量 $text 中提取段落?你也是对的,但我想从文本中提取段落而不是文件句柄
  • @smith 在这种情况下,编写一个正则表达式,并使用split。这将产生类似的效果:my @paragraphs = split /\n\n+/, $text 用于严格设置,IRL 我倾向于使用/\s*?\n\s*\n/ 正则表达式将仅包含空格的行视为空行。
  • @smith :我添加了一个示例,显示如何打开字符串的文件句柄...希望对您有所帮助
【解决方案2】:

您已经有了脚本 (local $/ = "";) 的答案,但值得注意的是,单行语句有一个快捷方式:-00 选项。

perl -00 -ne '$count++; END {print "Counted $count paragraphs\n"}' somefile.txt

来自man perlrun

-0[八进制/十六进制]

指定输入记录分隔符 ($/) [...]

特殊值 00 将导致 Perl 在段落中 slurp 文件 模式。

【讨论】:

    【解决方案3】:

    如果文本在变量中,例如:

    $text = "Here is a paragraph.\nHere is another paragraph.";
    

    或:

    $text = 'Paragraph 1
    Paragraph2';
    

    你可以通过用“\n”分割文本来简单地得到段落。

    @paragraphs = split("\n",$text);
    

    如果您的段落由双换行符或 \n 和 \r 的组合分隔(如在 Windows 中),您可以相应地更改拆分命令。

    【讨论】:

    • OP 的原始代码已经表现得像这样(当没有设置$/ 时),而且它不需要将整个文件读入内存来做到这一点。
    猜你喜欢
    • 2019-08-14
    • 2021-09-04
    • 1970-01-01
    • 2011-07-15
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多