У меня есть это приложение-викторина, в котором я подбираю правильный ответ по тому, что люди набирают. На данный момент я в основном вот что:
if ($input =~ /$answer/i) {
print "you won";
}
Приятно, что если ответ - «рыба», пользователь может набрать «рыба» и будет считаться хорошим ответом.
Проблема, с которой я столкнулся, заключается в том, что мои пользователи, поскольку я француз, и я хотел бы иметь возможность принимать, скажем, пользователя, вводящего «taton», а ответ - «tâton».
Итак, что я мог сделать, это:
use POSIX qw(locale_h);
use locale;
setlocale(LC_TYPE, "fr_FR.ISO8859-15");
setlocale(LC_COLLATE, "fr_FR.ISO8859-15");
И в моей программе проверки сделайте следующее:
$input = lc($input);
$input =~ tr/àáâãäåçèéêëìíîïñòóôõöùúûüýÿ/aaaaaaceeeeiiiinooooouuuuyy/;
и что-то подобное с ответом.
Мне это не нравится, потому что мне приходится жестко кодировать вещи, и в тот день, когда я решу, что ухожу из мира ISO-8859-15 в мир UTF-8, я обречен.
Итак, я ищу способ сравнить строки, который сделает "tâton" eq "taton", "maçon" eq "macon" или "macon" =~ /maçon/ верными.
Это был просто пример, и, ну, они также могли каждый раз набирать весь словарь :-)
Вы, вероятно, захотите, чтобы там были какие-то границы слов: m / \ b $ answer \ b /





Попробуйте модуль Текст :: Без акцента от CPAN (или Текст :: Unaccent :: PurePerl).
Это не похоже на подходящий повод для вызова регулярных выражений - у вас должен быть просто список приемлемых ответов, плюс некоторая фильтрация для удаления несущественных слов, таких как «a», «the» и их языковых эквивалентов.
Что бы вы ни делали, мне кажется очевидным, что это должно быть с учетом кодировки символов и языков. Регулярные выражения обычно не являются ни тем, ни другим.
Обратной стороной является то, что пользователь мог набрать: «эгоистичные гномы», и они все равно были бы правы.