2013-08-09 2 views
2

Список слов очень длинный, я не могу вставить фактический код, который здесь находится. Регулярное выражение белый список имеет около 4500 слов в нем, отделяемых |Actionscript regex false negative

И регулярное выражение, Whitelist и whitelist2 включает слово привет но тест для каждого возвращает разные результаты, и я понятия не имею, почему после тестирования то же самое с JavaScript, который дает правильные результаты.

Вот пример действия для тестирования. Линия для белого списка может быть не видна целиком, попробуйте скопировать код вставки из приведенной ниже ссылки в текстовом редакторе. http://wonderfl.net/c/jTmb/

Редактировать 1: проблема, с которой я сталкиваюсь, заключается в том, что иногда слова не являются точным соответствием. Пример субботы должен соответствовать субботе. Его почему я использовал регулярное выражение.

О строке длины. Я попытался проверить длину строки и ее сообщение правильно. http://wonderfl.net/c/a9yp/

Edit2: тест показывает, что работает в JavaScript http://tinyurl.com/m74hmdj

+0

На некоторых форумах я видел, что он сказал, что максимальное количество символов в строке ActionScript равно 1022. Может быть, это мешает? – tsiki

+0

Ох. Я думал, что это может быть некоторое ограничение на длину строки в actionscript. 1-й день попыток что-то в actionscript .. Спасибо, посмотрим. –

+0

О строке длина. Вероятно, вы вряд ли ударите максимальную длину строки AS3 - это 2 гигабайта - не помню, если это в UTF-16, что составило бы не менее 1 миллиарда символов. – JimmiTh

ответ

0

Я думаю @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); 

ETA: Производительность

Вот некоторые сравнения производительности.

  • _array предварительно инициализируется строчной массив строк, расщепленного |.
  • _regex предварительно инициализирован вашим регулярным выражением.
  • _search предварительно инициализирован заданным словом для поиска.

Я использую ваши слова до (включительно) слова, начинающиеся с L - обойти ограничения максимальной длины регулярного выражения:

Код для каждого теста:

regex.test:

_regex.test(_search); 

массив.IndexOf:

_array.indexOf(_search.toLowerCase()) >= 0; 

цикл по массиву:

for (var j:int = 0; j < _array.length; j++) 
{ 
    if (_array[j] == _search) 
    { 
     break; 
    } 
} 

Update: петля, IndexOf (проверить, если строка поиска подстроки элемента в белый список):

for (var j:int = 0; j < _array.length; j++) 
{ 
    if (_search.indexOf(array[j]) !== -1) 
    { 
     break; 
    } 
} 

AS3 компилятор не делает никакой несправедливой оптимизации этого простого кода (например, пропуски выполнения из-за не использования результата - это не все так умно).

10 трасс, 1000 итераций каждый, FP 11.4.402.278 - релиз версия:

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 

Это совершенно ясно, что цикл по массиву и сравнения каждого значения быстрее, чем при использовании регулярных выражений. Вы могли бы провести справедливое сравнение, прежде чем оно догонило бы время, которое проводит сравнение регулярных выражений. И в любом случае мы имеем дело с долями миллисекунд для одного поиска - это действительно преждевременная оптимизация, если вы не выполняете сотни запросов за короткий промежуток времени. Если мы были говорить оптимизации, Vector.<String> может ускорить вещи немного больше, по сравнению с Array.

Главное в этом состоит в том, что, за исключением относительно сложных сценариев, регулярное выражение вряд ли будет более эффективным, чем адаптированный парсер/сопоставление/поиск - который подходит для всех языков. Он разработан как инструмент общего назначения, а не для того, чтобы делать все самое умное в каждом случае (или почти в любом случае, если на то пошло).

+0

Спасибо за ответ. Но, как вы упомянули, в нижнем регистре проблема. Еще одна проблема, с которой я сталкиваюсь, заключается в том, что иногда слова не являются точным соответствием. Пример субботы должен соответствовать субботе. Его почему я использую регулярное выражение. –

+0

Как уже упоминалось, строчные буквы не являются проблемой, конвертируют белый список в нижний регистр, преобразуют ввод в нижний регистр, сравнивают. Готово. Если вы сравниваете неточные совпадения, тем больше причин избежать использования регулярных выражений - такое длинное регулярное выражение станет быстродействующим процессором и памятью *. Но вам потребуется дополнительная информация о ваших реальных требованиях, чтобы предложить что-либо. – JimmiTh

+0

Строка, в которой я буду проходить, составляет около 100 символов. Белый список предназначен для ругательного фильтра. Цикл while без регулярного выражения занимает около 50-100 мс на моем четырехъядерном ядре. Сложное регулярное выражение должно занимать более короткое время, я думаю. Фактический код проходит через одно слово за раз, если он обнаруживает, что конкретное слово в предложении находится в «черном списке», я планирую протестировать его против белого списка. –

1

Фактический ответ ...

Этот вопрос привел меня в поиске некоторые интересные ограничения AS3 впервые ...

Ваш регулярное выражение не может в длину он имеет под словом «metabrushite». Насколько я могу судить по различным тестам, это то место, где он достигает самой длинной поддерживаемой длины регулярного выражения в AS3: 31391 символов. Любое регулярное выражение дольше, чем кажется всегда возвращение false по вызову test(). Обратите внимание, что «Hello» появляется в списке до «metrrushite», поэтому это не вопрос усечения - регулярное выражение просто не работает вообще - например. регулярное выражение, которое всегда должно возвращать true для все слов, все еще возвращает false, если это так долго.

Предел кажется довольно произвольным числом, поэтому трудно точно сказать, что делает этот предел.

Опять же, вы действительно не должны использовать регулярное выражение для такой задачи, но если вы чувствуете, что у вас есть, вам нужно разбить его на несколько регулярных выражений, каждый из которых не превышает максимальная длина.

Примечание стороны:

Еще одна интересная вещь, которую я не рассмотрел более внимательно, что создание RegExp из каскадного строки одного заявления, а именно:

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

.. ,приведет к сбою даже для более коротких результирующих строк. Кажется, это связано с максимальной длиной, налагаемой на длину одного оператора, и не имеет никакого отношения к регулярному выражению. Он не замерзает; он не выводит ошибку или даже первый trace. Сценарий просто молча отключается от swf и, следовательно, никогда не выполняется.

+0

Да, я попытался сделать indexOf на этой строке, чтобы найти слово hello, которое сработало, но regex все еще не работал. Затем я вспомнил этот сайт для тестирования регулярных выражений, который был основан на flash. Поэтому я экспериментировал с количеством элементов/длиной строки регулярного выражения. http://gskinner.com/RegExr/ http: // pastebin.com/UJzeHTy4 Если вы поместите слово hello в текстовый абзац и шаблон регулярного выражения из ссылки pastebin в текстовое поле шаблона на gskinner.com, оно принимает только 30707 символов, после чего оно возвращает false для всех. –

+0

Различные максимальные числа, которые мы получаем, могут указывать на то, что внутреннее представление регулярного выражения устанавливает предел, а не длину строки. – JimmiTh

Смежные вопросы