Actionscript 3 Actionscript正则表达式假阴性

Actionscript 3 Actionscript正则表达式假阴性,actionscript-3,Actionscript 3,单词列表很长,我无法将实际的错误代码粘贴到这里。 regex白名单中约有4500个单词,由| regex、whitelist和whitelist2都包含hello这个词,但是对每个词的测试都会返回不同的结果,我不知道为什么在使用javascript测试后会得到正确的结果 下面是用于测试的操作脚本。 白名单的行可能不完全可见,请尝试在文本/代码编辑器中从下面的链接复制粘贴代码。 Edit1:我面临的问题是,有时这些词并不完全匹配。 示例周六需要与周六匹配。 这就是我使用正则表达式的原因 关于字符

单词列表很长,我无法将实际的错误代码粘贴到这里。 regex白名单中约有4500个单词,由|

regex、whitelistwhitelist2都包含hello这个词,但是对每个词的测试都会返回不同的结果,我不知道为什么在使用javascript测试后会得到正确的结果

下面是用于测试的操作脚本。 白名单的行可能不完全可见,请尝试在文本/代码编辑器中从下面的链接复制粘贴代码。

Edit1:我面临的问题是,有时这些词并不完全匹配。 示例周六需要与周六匹配。 这就是我使用正则表达式的原因

关于字符串长度。 我试着检查字符串的长度以及它是否被正确报告。

编辑2: 测试表明它在javascript中工作
我认为@tsiki关于AS3正则表达式的最大长度是正确的

这确实是一个注释,但由于我想包含一些代码,我将其作为一个答案:

因为除了使用<代码> > 分隔的单词列表之外,您不使用正则表达式,请考虑使用数组来代替。这种方法的另一个优点是速度会快很多

// This is just a way of reusing your list,
// rather than manually transforming it to an array:
var whitelist:Array = "abasement|abastardize|abastardize|..."
                      .split("|");

// Simply use .toLowerCase() on the input string to make it case insensitive,
// assuming all your whitelist words are lower case.
trace(whitelist.indexOf("hello") >= 0);
预计到达时间:性能

下面是一些性能比较

  • \u数组
    预先初始化为字符串的小写数组,由
    拆分
  • \u regex
    已预初始化为您的regex
  • \u search
    预先初始化为要搜索的给定单词
我使用最多(包括)以
L开头的单词来绕过最大正则表达式长度限制:

每个测试的代码:

regex.test:

_regex.test(_search);
array.indexOf:

_array.indexOf(_search.toLowerCase()) >= 0;
循环阵列:

for (var j:int = 0; j < _array.length; j++)
{
   if (_array[j] == _search)
   {
      break;
   }
}
很明显,在数组上循环并比较每个值比使用正则表达式要快。在它赶上正则表达式比较所花费的时间之前,您可以做一些比较。在任何情况下,我们都在处理一次查找的毫秒数-这真的是过早的优化,除非你在短时间内进行数百次查找。如果我们说的是优化,
向量。
可能比
数组
的速度稍微快一些

这整件事的要点是,除了相对复杂的场景外,正则表达式不太可能比定制的解析器/比较器/查找更高效——这适用于所有语言。它被设计成一个通用工具,而不是在任何情况下(或在任何情况下)都以最聪明的方式做事。

实际答案

这个问题让我第一次发现了一些有趣的AS3限制

您的正则表达式失败的长度为单词“metabrushite”。从各种测试中可以看出,这是AS3中正则表达式支持的最长长度:31391个字符。在调用
test()
时,任何长于该值的正则表达式似乎总是返回
false
。请注意,“hello”出现在“metabrushite”之前的列表中,因此这不是截断的问题-正则表达式根本无法正常工作-例如,对于所有单词,始终应返回
true
的正则表达式,如果那么长,仍然返回
false

这个极限似乎是一个相当任意的数字,所以很难确切地说出是什么造成了这个极限

同样,您真的不应该在这样的任务中使用正则表达式,但是如果您觉得必须这样做,您需要将它分成几个正则表达式,每个正则表达式都不超过最大长度

旁注:

另一件有趣的事情,我没有仔细研究过,就是从单个语句连接字符串创建
RegExp
,即:

trace("You'll never see this traced if too many words are added below.");
var s:String = "firstword|" +
               "secondword|" +
               ... +
               "lastword";

。。。对于更短的结果字符串,将失败。这似乎是由于对单个语句的长度施加了最大长度,而与正则表达式无关。它不会结冰;它不会输出错误,甚至不会输出第一个
跟踪
。该脚本只是被悄悄地从swf中排除,因此从未执行。

在一些论坛上,我看到它说actionscript行中的最大字符数是1022。也许这是干扰?哦。我在想,在actionscript中,字符串的长度是否也有一些限制。在actionscript中尝试某些内容的第一天。。谢谢,我来看看。关于绳子的长度。您不太可能达到AS3的最大字符串长度-它是2GB-不记得是否在UTF-16中,这将使它至少有10亿个字符。是的,我测试了它,它没有达到限制。@Prathamsgharat很抱歉我的问题,但是为什么要使用正则表达式来查找简单字符串?我想你正在使用它,因为你需要找到一个复杂的模式?。在其他情况下,你可以使用字符串函数来搜索这个词。谢谢你的回复。但是正如你提到的,小写是个问题。我面临的另一个问题是,有时单词并不完全匹配。示例周六需要与周六匹配。这就是我使用正则表达式的原因。如前所述,小写不是问题,将白名单转换为小写,将输入转换为小写,比较。完成。如果你比较的是不精确的匹配,那么就更应该避免使用正则表达式——这样长的正则表达式会占用大量的CPU和内存。但需要更多关于您实际需求的信息才能提出建议。我将要讨论的字符串长度约为100个字符。白名单是一个诅咒过滤器。没有regex的while循环在我的四核上大约需要50-100ms。我认为编译正则表达式所需的时间应该更短。如果实际代码发现句子中的某个单词是
Method            Search for       Avg.        Min       Max          Iter.
---------------------------------------------------------------------------
array.indexOf     "abasement"    0.0 ms       0 ms      0 ms           0 ms
regex.test        "abasement"   18.4 ms      14 ms     22 ms      0.0184 ms
loop over array   "abasement"    0.0 ms       0 ms      0 ms           0 ms
loop, indexOf     "abasement"    0.0 ms       0 ms      0 ms           0 ms

array.indexOf     "hello"       31.1 ms      25 ms     42 ms      0.0311 ms
regex.test        "hello"      326.8 ms     309 ms    347 ms      0.3268 ms
loop over array   "hello"       59.4 ms      50 ms     69 ms      0.0594 ms
loop, indexOf     "hello"       97.4 ms      92 ms    105 ms      0.0974 ms

Avg.  = average time for the 1000 iterations in each run
Min   = Minimum time for the 1000 iterations in each run
Max   = Maximum time for the 1000 iterations in each run
Iter. = Calculated time for a single iteration on average
trace("You'll never see this traced if too many words are added below.");
var s:String = "firstword|" +
               "secondword|" +
               ... +
               "lastword";