C++11 正则表达式搜索 - 排除空子匹配

C++11 Regex search - Exclude empty submatches

我想从以下文本中提取 numberunit of measurement

我有两种可能的情况:

这是一些文字 14.56 kg 和一些其他文字

这是一些文字kg 14.56和一些其他文字

我使用 | 来匹配这两种情况。 我的问题是它会产生空的子匹配项,因此给我的匹配项数量不正确。

这是我的代码:

std::smatch m;
std::string myString = "This is some text kg 14.56 and some other text";

const std::regex myRegex(
        R"(([\d]{0,4}[\.,]*[\d]{1,6})\s+(kilograms?|kg|kilos?)|s+(kilograms?|kg|kilos?)(\s+[\d]{0,4}[\.,]*[\d]{1,6}))",
        std::regex_constants::icase
);

if( std::regex_search(myString, m, myRegex) ){
    std::cout << "Size: " << m.size() << endl;
    for(int i=0; i<m.size(); i++)
        std::cout << m[i].str() << std::endl;
}
else
    std::cout << "Not found!\n";

输出:

Size: 5
kg 14.56


kg
14.56

我想要一种简单的方法来提取这 2 个值,所以我猜想我需要以下输出:

想要的输出:

Size: 3
kg 14.56
kg
14.56

这样我总是可以直接提取第2和第3个,但在这种情况下我还需要检查哪个是数字。我知道如何通过 2 个单独的搜索来完成,但我想以正确的方式进行,通过一次搜索而不使用 c++ 检查子匹配是否为空字符串。

你可以试试这个:

((?:(?<!\d)(\d{1,4}(?:[\.,]\d{1,6})?)\s+((?:kilogram|kilos|kg)))|(?:((?:kilogram|kilos|kg))\s+(\d{1,4}(?:[\.,]\d{1,6})?)))

如图所示:https://regex101.com/r/9O99Fz/3

用法 -

如我在 'substitution' 部分所示,要引用数量的数字部分,您必须编写 $2$5,单位写:$3$4

解释-

我们可能需要两个捕获组:这里的第一个 (?:(?<!\d)(\d{1,4}(?:[\.,]\d{1,6})?)\s+((?:kilogram|kilos|kg))) 是匹配数字后跟单位,
和另一个 (?:((?:kilogram|kilos|kg))\s+(\d{1,4}(?:[\.,]\d{1,6})?)) 匹配单位后跟数字

使用这个正则表达式,你只需要第 1 组和第 2 组的内容

((?:kilograms?|kilos?|kg)|(?:\d{0,4}(?:\.\d{1,6})))\s*((?:kilograms?|kilos?|kg)|(?:\d{0,4}(?:\.\d{1,6})))

Click for Demo

解释:

  • ((?:kilograms?|kilos?|kg)|(?:\d{0,4}(?:\.\d{1,6})))
    • (?:kilograms?|kilos?|kg) - 匹配 kilogramskilogramkiloskilokg
    • | - 或者
    • (?:\d{0,4}(?:\.\d{1,6})) - 匹配 0 到 4 位后跟小数部分的 1 到 6 位
  • \s* - 匹配 0+ 个空格