- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试计算文档中 12 个单词的窗口中出现 3 个单词的短语的次数,但困难在于我要搜索的关键字可以分布在整个窗口中。
例如:
我想在一个 12 个单词的短语中找到短语“expect bad weather”,其中可以在 3 个所需单词之间插入其他单词,只要包含 3 个单词的总短语不超过 12 个单词.
有效的短语:
我一直在努力弄清楚如何做到这一点。我知道如何计算两个单词之间可能存在差距的短语的出现次数。例如,如果我计算“expect”和“weather”在 12 个词的短语中出现的频率,我可以这样做:
$mycount =()= $text =~ /\b(?:expect\W+(?:\w+\W+){0,10}?weather)\b/gi;
但是,当我想用 3 个单词执行此操作时,它并不那么简单,因为我最终得到 2 个必须加在一起的间隙,以便我的窗口不超过 12 个单词。理想情况下,我可以做类似的事情:
$mycount =()= $text =~ /\b(?:expect\W+(?:\w+\W+){0,$Gap1}?bad\W+(?:\w+\W+){0,$Gap2}?weather)\b/gi;
其中 $Gap2 = 9 - $Gap1,但我认为没有办法做到这一点。
我还想过创建一个循环,以便在循环的一次迭代中 $Gap1=0 和 $Gap2=9,在第二次迭代中 $Gap1=1 和 $Gap2=8,等等,然后添加计数所有的循环。但是,这样做会重复计算该短语的某些实例。
我很迷茫。有人有什么想法吗?我在任何地方都找不到任何相关示例。
最佳答案
注意 这篇文章解决了查找在一个窗口内展开的单词的问题,正如所问的那样。它没有考虑更复杂的一般文本解析或语言分析问题。
下面的代码搜索第一个单词,然后继续使用另一个正则表达式搜索其他两个单词。它在那里逐字扫描文本并保留一个计数器,因此它可以在 12 个字处停止。它使用 pos
来控制在检查窗口后应该从哪里继续。
一旦找到 12 长的窗口,就会以单词 expect
开头,如评论中所述。在完成的短语之后继续搜索下一个。
如果在接下来的 11 个单词中没有找到该短语,引擎将返回到 expect
之后的位置以继续搜索(因为可能还有另一个 expect
在选中的 11 个单词内)。
use warnings;
use strict;
use feature 'say';
my $s = q(I expect, although no one confirmed, that bad weather is on the way.)
. q( Expect that we cannot expect to escape the bad, bad weather.);
my $word_range = 12;
my ($w1, $w2, $w3) = qw(expect bad weather);
FIRST_WORD: while ($s =~ /\b($w1)\b/gi) {
#say "SEARCH, at ", pos $s;
my ($one, $pos_one) = ($1, pos $s);
my ($two, $three, $cnt);
while ($s =~ /(\w+)/g) {
my $word = $1;
#say "\t$word ... (at ", pos $s, ")";
$two = $1 if $word =~ /\b($w2)\b/i;
if ( $two and (($three) = $word =~ /\b($w3)\b/i) ) {
say "$one + $two + $three (pos ", pos $s, ')';
next FIRST_WORD;
}
last if ++$cnt == $word_range-1; # failed (these 11 + 'expect')
}
pos $s = $pos_one; # return to position in string after 'expect'
}
请注意,不能在循环条件内分配匹配项(对于 $one
),因为这会将匹配项放入列表上下文中,从而扰乱了 /g
所需的行为> 和 pos .
被注释掉的打印可以用来跟踪操作。按照目前的情况打印
expect + bad + weather (pos 53)Expect + bad + weather (pos 128)
I extend the string to test multiple occurrences of the phrase. The operation with failed matches can be tested by crippling keywords and tracking the position in the search.
A possible extra keyword inside of the phrase, as in the second sentence, is ignored and the phrase is accepted if there, as this is unspecified but implicit in the question. This is easily changed.
If there were more words in the phrase they would all be sought in the inner while
loop, in the same way as the last two are now, by matching them sequentially (requiring for each word that all preceding words had been found). The outer while
loop is needed only to start the window.
After a failed window-scan the outer while
continues its search for expect
from the position of the window beginning, thus scanning the same 11 words again.
This repeated search through the text can be reduced by checking for expect
as well during the window scan. Then scan afresh from that position, with the inner while
# First sentence shortened and now does not contain the phrase
my $s = q(I expect, although no one confirmed, that bad expect.)
. q( Expect that we cannot expect to escape the bad, bad weather.);
...
FIRST_WORD: while ($s =~ /\b($w1)\b/gi) {
my ($one, $pos_one) = ($1, pos $s);
my ($two, $three, $cnt, $pos_one_new);
while ($s =~ /(\w+)/g) {
my $word = $1;
#say "\t$word ... (at ", pos $s, ")";
$pos_one_new = pos $s
if not $pos_one_new and $word =~ /\b$w1\b/i;
$two = $1 if $word =~ /\b($w2)\b/i;
if ( $two and (($three) = $word =~ /\b($w3)\b/i) ) {
say "$one + $two + $three (pos ", pos $s, ')';
next FIRST_WORD;
}
if (++$cnt == $word_range-1) {
last if not $pos_one_new;
#say "Scan window anew from $pos_one_new";
pos $s = $pos_one_new;
$pos_one = $pos_one_new;
$pos_one_new = 0;
$two = $three = '';
$cnt = 0;
}
}
pos $s = $pos_one;
}
这打印
expect + bad + weather (pos 113)
请注意,使用了窗口中 第一次 出现的 expect
。
关于Perl:如何计算在 N 字窗口中出现 3 字词组(有间隙)的次数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48454477/
我正在维护一些 Java 代码,我目前正在将它们转换为 C#。 Java 代码是这样做的: sendString(somedata + '\000'); 在 C# 中,我正在尝试做同样的事情: sen
如何确定函数中传递的参数是字符串还是字符(不确定如何正确调用它)文字? 我的函数(不正确): void check(const char* str) { // some code here }
我真的不知道如何准确地提出这个问题,但我希望标题已经说明了这一点。 我正在寻找一种方法(一个框架/库),它提供了执行 String.contains() 函数的能力,该函数告诉我给定的字符串是否与搜索
我正在尝试编写一些读取 Lambda 表达式并输出 beta 缩减版本的东西。 Lambda 的类型如下:\variable -> expression,应用程序的形式为 (表达式) (表达式)。因此
StackOverflow 上的第 1 篇文章,如果我没能把它做好,我深表歉意。我陷入了一个愚蠢的练习,我需要制作一个“刽子手游戏”,我尝试从“.txt”文件中读取单词,然后我得到了我的加密函数,它将
我想在 Groovy 中测试我的 Java 自定义注释,但由于字符问题而未能成功。 Groovyc: Expected 'a' to be an inline constant of type cha
当我尝试在单击按钮期间运行 javascript location.href 时,出现以下错误“字 rune 字中的字符过多”。 最佳答案 这应该使用 OnClientClick相反? 您可能还想停
我想要类似的东西: let a = ["v".utf8[0], 1, 2] 我想到的最接近的是: let a = [0x76, 1, 2] 和 "v".data(using: String.Encod
有没有办法在 MySQL 中指定 Unicode 字 rune 字? 我想用 Ascii 字符替换 Unicode 字符,如下所示: Update MyTbl Set MyFld = Replace(
阅读 PNG 规范后,我有点惊讶。我读过字 rune 字应该用像 0x41 这样的二进制值进行硬编码,而不是在(程序员友好的)'A' 中。问题似乎是在具有不同底层字符集的不同系统上编译期间字 rune
考虑一个具有 UTF-8 执行字符集的 C++11 编译器(并且符合要求 char 类型为有符号 8 位字节的 x86-64 ABI) . 字母 Ä(元音变音)具有 0xC4 的 unicode 代码
为什么即使有 UTF-8 字符串文字,C11 或 C++11 中也没有 UTF-8 字 rune 字?我知道,一般来说,字 rune 字表示单个 ASCII 字符,它与单字节 UTF-8 代码点相同,
我怎样才能用 Jade 做到这一点? how would I do this 我几乎可以做任何事情,除了引入一个 span 中间句子。 最佳答案 h3.blur. how would I do t
这似乎是一个非常简单的问题,但我只是想澄清我的疑问。我正在查看其他开发人员编写的代码。有一些涉及 float 的计算。 示例:Float fNotAvlbl = new Float(-99); 他为什
我想知道第 3 行“if dec:”中的“dec”是什么意思 1 def dec2bin(dec): 2 result='' 3 if dec:
我试图在字符串中查找不包含任何“a”字符的单词。我写了下面的代码,但它不起作用。我怎么能对正则表达式说“不包括”?我不能用“^”符号表示“不是”吗? import re string2 = "asfd
这个问题在这里已经有了答案: Is floating point math broken? (31 个答案) Is floating point arbitrary precision availa
我正在创建一个时尚的文本应用程序,但在某些地方出现错误(“字 rune 字中的字符太多”)。我只写了一个字母,但是当我粘贴它时,它会转换成许多这样的字母:“\uD83C\uDD89”,原始字母是“🆉
我正在尝试检查用户是否在文本框中输入了一个数字值,是否接受了小数位。非常感谢任何帮助。 Private Sub textbox1_AfterUpdate() If IsNumeric(textbox1
我知道一个 Byte 是 8 位,但其他的代表什么?我正在参加一个使用摩托罗拉 68k 架构的汇编类(class),我对目前的词汇感到困惑。 最佳答案 如 operator's manual for
我是一名优秀的程序员,十分优秀!