Диакритические знаки в регулярном выражении вызывают неожиданное поведение - PullRequest
0 голосов
/ 16 марта 2020

Я проверяю правильность имени с помощью этого регулярного выражения, позволяя использовать любой символ в соответствии с предложением здесь :

// Allow any symbol
const QString validNameMatcher = QStringLiteral("^[a-zA-Z0-9 _.,!()+=`,\"@$#%*-]+$");

bool Class::isNameValid(const QString fileName)
{
    QRegularExpression re(validNameMatcher);
    QRegularExpressionMatch match = re.match(fileName);

    if (match.hasMatch())
        return true;
    else
        return false;
}

Для имени файла, например 1111 Rick (wow) L50-57.stl, вышеуказанная функция возвращает true. Пока все хорошо.


Чтобы разрешить диакритические знаки, я просто добавляю [À-ž] к сопоставителю имен в соответствии с предложением здесь :

// [À-ž] is for diacritical marks
const QString validNameMatcher = QStringLiteral("^[a-zA-Z0-9À-ž _.,!()+=`,\"@$#%*-]+$");

После неожиданно добавив [À-ž] для того же имени файла 1111 Rick (wow) L50-57.stl, вышеприведенная функция возвращает false. Я что-то упустил?


ОБНОВЛЕНИЕ

Как подсказывает @ WiktorStribiżew, я использовал UseUnicodePropertiesOption:

QRegularExpression re(validNameMatcher, QRegularExpression::PatternOption::UseUnicodePropertiesOption);

Но это не сработало. Результат такой же, как и раньше.

Также (*UTF) не работает:

const QString validNameMatcher = QStringLiteral("(*UTF)^[a-zA-Z0-9À-ž _.,!()+=`,\"@$#%*-]+$");

1 Ответ

0 голосов
/ 16 марта 2020

Ключевым моментом является @ WiktorStribi - новое решение использования опции QRegularExpression::UseUnicodePropertiesOption:

QRegularExpression re(validNameMatcher, QRegularExpression::PatternOption::UseUnicodePropertiesOption);

Но, как указано в его документации :

QRegularExpression: : UseUnicodePropertiesOption

Значение \ w , \ d , et c., Классов символов, а также значение их аналогов (\ W , \ D и т. Д. c.) Изменяется с сопоставления только символов ASCII на сопоставление любого символа с соответствующим свойством Unicode.

Итак, мне пришло в голову заменить [a-zA-Z0-9À-ž_] в моем регулярное выражение с [\w]:

// Bad:
const QString validNameMatcher = QStringLiteral("^[a-zA-Z0-9À-ž _.,!()+=`,\"@$#%*-]+$");

// Good:
const QString validNameMatcher = QStringLiteral("^[\\w .,!()+=`,\"@$#%*-]+$");

Теперь функция isNameValid() возвращает ожидаемые результаты.

...