正则表达式可以匹配引号外的所有单词吗?

时间:2014-09-23 20:02:55

标签: regex language-agnostic match

我最近为我的点燃课程输入了一篇文章,我的老师特别声明了一个不包含该文章引文的字数限制。我想,为什么不制作一个为你计算的脚本呢?当然,我可以通过浏览整个文本并忽略引号内的单词来做这个无聊的方式,但我感觉有一种更简洁的方式使用正则表达式和Array.count。正如我对Regex几乎一无所知,有人可以帮我/告诉我这是不可能的正则表达式吗?

Tl; dr:使用正则表达式来匹配文本中引号外的所有单词(或空格,无关紧要),并计算结果数组中的项目。

4 个答案:

答案 0 :(得分:6)

根据要求,可以使用The Greatest Regex Trick Ever

"[^"]*"|(\w+)

计算第一个capture group的匹配项。

\w+匹配一个或多个单词字符。

请参阅test at regex101.com


同时跳过单引号字符串:

"[^"]*"|'[^']*'|(\w+)

test at regex101

答案 1 :(得分:2)

一般的解决方案非常困难,因为有些作品会有多段引号,第一段不会关闭引号,但第二段会打开引号。因此,在整个文档范围内匹配引号会很难。

另一方面,您可以逐段进行,并为每个段落累积一个非引用字数。当然,仍然存在可以打破这种情况的病例(如包含标点符号列表的段落,包括引号)。

在Perl中,假设getWordCount子存在于某处,并假设您以某种方式将文档拆分为一个名为@paragraphs的段落数组,这可能看起来像:

my $wordCount = 0;
foreach my $paragraph (@paragraphs) {
    $paragraph =~ s/\".*?\"/g; # remove all quotation marks which have a matching quotation mark
    $paragraph =~ s/\".*$/g; # remove quotation marks which go to the end of the paragraph
    $wordCount += getWordCount($paragraph);
}
print "There are $wordCount words outside of quotations, maybe!";

答案 2 :(得分:2)

使用PCRE(或Perl)当然很容易:

".*?"(*SKIP)(?!)|(?<!\w)'.*?'(?!\w)(*SKIP)(?!)|[\w']+

如果您想处理多行报价,请使用g修饰符和s

Demo

以下是x版本的可读性:

  ".*?"              (*SKIP)(?!)
| (?<!\w)'.*?'(?!\w) (*SKIP)(?!)
| [\w]+

第一部分将匹配"'引号内的所有内容,并将丢弃它((*SKIP)(?!))。第二部分将匹配所有单词(我已将'作为此示例中单词的一部分)。 '字符仅在单词的开头/结尾被计为引号边界,以便您使用 isn&#39; t 之类的内容。

可能的修改:

  • 要将文字不是计为两个字,请将[\w']+替换为\w+
  • 要将婆婆等文字计为一个单词而不是3个,请将[\w']+替换为[-\w']+

你明白了;)

这是一个使用此正则表达式的完整Perl脚本:

#!/usr/bin/env perl
use strict;
use warnings;

$_ = do { local $/; <> };
print scalar (() = /".*?"(*SKIP)(?!)|(?<!\w)'.*?'(?!\w)(*SKIP)(?!)|[\w']+/gs), "\n";

执行传递包含要计算单词的文本的文件或STDIN,它将在STDOUT上输出单词count。

答案 3 :(得分:1)

这样做会更好:

总字符数 - 总和(引号内的字符)

您可以使用此正则表达式查找所有&#34;引用&#34;字符串:\&#34; [^&#34;] * \&#34;