-4

给定一个 QString,我想从主字符串输入中提取一个子字符串。

例如,我有一个 QString 读取类似的内容:

\\\\?\\Volume{db41aa6a-c0b8-11e9-bc8a-806e6f6e6963}\\

我需要使用与正则表达式格式匹配的模板/格式来提取字符串(如果存在该格式的字符串)(\w){8}([-](\w){4}){3}[-](\w){12},如下所示:

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

它应该返回

db41aa6a-c0b8-11e9-bc8a-806e6f6e6963

如果找到,则为空QString

目前,我可以通过执行以下操作来实现这一点:

string.replace("{", "").replace("}", "").replace("\\", "").replace("?", "").replace("Volume", "");

但这是乏味且低效的,并且是针对特定要求量身定制的。

是否有一个通用函数使我能够使用正则表达式格式或其他格式提取子字符串?

更新

在@Emma 的回答之后为了清楚起见,我想要例如QString::extract("(\w){8}([-](\w){4}){3}[-](\w){12}")which 返回db41aa6a-c0b8-11e9-bc8a-806e6f6e6963

4

2 回答 2

2

这里有一堆方法来提取问题中提出的字符串的一部分。我不知道有多少字符串格式是固定的和可变的,所以可能并非所有这些示例都是实用的。此外,下面的一些示例使用的QStringRef类可能更有效,但在任何引用处于活动状态时必须使原始字符串(被引用的字符串)可用(请参阅文档中的警告)。

  const QString str("\\\\?\\Volume{db41aa6a-c0b8-11e9-bc8a-806e6f6e6963}\\");

  // Treat str as a list delimited by "{" and "}" chars.

  const QString sectResult = str.section('{', 1, 1).section('}', 0, 0);  // = "db41aa6a-c0b8-11e9-bc8a-806e6f6e6963"
  const QString sectRxResult = str.section(QRegExp("\\{|\\}"), 1, 1);    // = "db41aa6a-c0b8-11e9-bc8a-806e6f6e6963"

  // Example using QStringRef, though this could also be just QString::split() which returns QString copies.
  const QVector<QStringRef> splitRef = str.splitRef(QRegExp("\\{|\\}"));
  const QStringRef splitRefResult = splitRef.value(1);  // = "db41aa6a-c0b8-11e9-bc8a-806e6f6e6963"

  // Use regular expressions to find/extract matching string

  const QRegularExpression rx("\\w{8}(?:-(\\w){4}){3}-\\w{12}");  // match a UUID string
  const QRegularExpressionMatch match = rx.match(str);
  const QString rxResultStr = match.captured(0);        // = "db41aa6a-c0b8-11e9-bc8a-806e6f6e6963"
  const QStringRef rxResultRef = match.capturedRef(0);  // = "db41aa6a-c0b8-11e9-bc8a-806e6f6e6963"

  const QRegularExpression rx2(".+\\{([^{\\}]+)\\}.+");  // capture anything inside { } brackets
  const QRegularExpressionMatch match2 = rx2.match(str);
  const QString rx2ResultStr = match2.captured(1);       // = "db41aa6a-c0b8-11e9-bc8a-806e6f6e6963"
  // Make a copy for replace so that our references to the original string remain valid.
  const QString replaceResult = QString(str).replace(rx2, "\\1");   // = "db41aa6a-c0b8-11e9-bc8a-806e6f6e6963"

  qDebug() << sectResult << sectRxResult << splitRefResult << rxResultStr
           << rxResultRef << rx2ResultStr << replaceResult;
于 2019-11-18T04:40:26.180 回答
0

也许,

Volume{(\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b)}

要不就,

\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b

完整的比赛可能会更接近一点。


如果您希望简化/更新/探索表达式,它已在regex101.com的右上角面板中进行了说明。如果您有兴趣,可以在此调试器链接中观看匹配步骤或修改它们。调试器演示了 RegEx 引擎如何逐步使用一些示例输入字符串并执行匹配过程。


正则表达式电路

jex.im可视化正则表达式:

在此处输入图像描述

资源

使用正则表达式在文本中搜索 UUID

于 2019-11-17T19:19:08.193 回答