C++11 正则表达式搜索 - 排除空子匹配
C++11 Regex search - Exclude empty submatches
我想从以下文本中提取 number
和 unit 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})))
解释:
((?:kilograms?|kilos?|kg)|(?:\d{0,4}(?:\.\d{1,6})))
(?:kilograms?|kilos?|kg)
- 匹配 kilograms
或 kilogram
或 kilos
或 kilo
或 kg
|
- 或者
(?:\d{0,4}(?:\.\d{1,6}))
- 匹配 0 到 4 位后跟小数部分的 1 到 6 位
\s*
- 匹配 0+ 个空格
我想从以下文本中提取 number
和 unit 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})))
解释:
((?:kilograms?|kilos?|kg)|(?:\d{0,4}(?:\.\d{1,6})))
(?:kilograms?|kilos?|kg)
- 匹配kilograms
或kilogram
或kilos
或kilo
或kg
|
- 或者(?:\d{0,4}(?:\.\d{1,6}))
- 匹配 0 到 4 位后跟小数部分的 1 到 6 位
\s*
- 匹配 0+ 个空格