正则表达式中的变音符会导致意外行为

Diacritical marks in regular expression causes unexpected behavior

我通过这个正则表达式检查名称有效性,允许任何建议的符号 here:

// 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这样的文件名,上面的函数returnstrue。到目前为止一切顺利。


为了允许变音符号,我只是按照建议将 [À-ž] 添加到名称匹配器中 :

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

加上[À-ž]后,意外的是,对于1111 Rick (wow) L50-57.stl相同的文件名,上面的函数returnsfalse。我错过了什么吗?


更新

根据@WiktorStribiżew 的建议,我使用了 UseUnicodePropertiesOption:

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

但是没有用。结果和之前一样。

另外 (*UTF) 不起作用:

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

关键点是@WiktorStribiżew 使用 QRegularExpression::UseUnicodePropertiesOption 选项的解决方案:

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

但正如其 documentation 中所述:

QRegularExpression::UseUnicodePropertiesOption

The meaning of the \w, \d, etc., character classes, as well as the meaning of their counterparts (\W, \D, etc.), is changed from matching ASCII characters only to matching any character with the corresponding Unicode property.

所以,我想到将正则表达式中的 [a-zA-Z0-9À-ž_] 替换为 [\w]:

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

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

现在,isNameValid() 函数 returns 预期结果。