我正在加载一个包含以下行的.obj文件
vn 8.67548e-017 1 -1.55211e-016
这是用于顶点法线的。如何检测并将它们转换为双精度符号?
一个相当有效的正则表达式是:
-?[\d.]+(?:e-?\d+)?
可以像这样将字符串转换为数字:String in scientific notation C++ to double conversion。
正则表达式是:
-? # an optional -
[\d.]+ # a series of digits or dots (see *1)
(?: # start non capturing group
e # "e"
-? # an optional -
\d+ # digits
)? # end non-capturing group, make optional
**1)从技术上讲,这并不完全正确。在点之前只能有一个(或没有)数字,并且只能有一个点。但在实践中,这种情况应该不会发生。因此,正则表达式是一个很好的近似值,假阳性的可能性非常小。请随意使正则表达式更具体。
您可以使用正则表达式-?\d*\.?\d+e[+-]?\d+
来识别科学数值。
{0,1}
,请改用 ?
。前者更长,没有更清晰的效果,并且具有相同的作用。 - Antal Spector-Zabusky{0,1}
可以被替换为 ?
。但是,为什么要让小数点变成可选项呢?这也不允许负数。它还会错误地匹配 .0
,这可能不是所需的结果。 - moinudin我尝试了其他一些解决方案都无效,所以我想出了这个。
^(-?\d+)\.?\d+(e-|e\+|e|\d+)\d+$
任何与之匹配的内容都被认为是有效的科学计数法。
请注意:此正则表达式接受e+
、e-
和e
;如果您不想接受e
,可以使用这个:^(-?\d+)\.?\d+(e-|e\+|\d+)\d+$
我不确定它是否适用于C++,但在C#中,您可以在正则表达式的^
和(-
之间添加(?i)
来切换行内大小写不敏感性。没有它,像1.05E+10
这样声明的指数将无法被识别。
编辑:我的先前的正则表达式有一些小问题,所以我已经用上面的替换了它。
^(?:-?\d*)\.?\d+[eE][-\+]?\d+$
-- 允许像 .1e5
这样的情况,在 JS 中是有效的。 - Jacob\d+
呢?这将使你的正则表达式匹配非科学计数法形式的数字,如 3.1415
。 - Paul Razvan Berg如果您确定double类型的格式是科学计数法,可以尝试以下方式:
string inp("8.67548e-017");
istringstream str(inp);
double v;
str >> scientific >> v;
cout << "v: " << v << endl;
在C++中使用std::regex
提取科学计数法中的数字,我通常会使用以下方法:
((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?((e|E)((\\+|-)?)[[:digit:]]+)?
这对应于
((\+|-)?\d+)(\.((\d+)?))?((e|E)((\+|-)?)\d+)?
这将匹配任何形式为+12.3456e-78
的数字,其中
+
或-
,并且是可选的相应的解析代码可能如下所示:
std::regex const scientific_regex {"((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?((e|E)((\\+|-)?)[[:digit:]]+)?"};
std::string const str {"8.67548e-017 1 -1.55211e-016"};
for (auto it = std::sregex_iterator(str.begin(), str.end(), scientific_regex); it != std::sregex_iterator(); ++it) {
std::string const match {it->str()};
std::cout << match << std::endl;
}
double
数字,std::stod
应该能够正确地处理转换,正如 Ben Voigt 所指出的那样。
好吧,这并不完全是你要求的,因为它不是 Perl(噫)而且它是一个普通定义而不是正则表达式,但这就是我用来识别 C 浮点文字面量扩展(该扩展允许数字字符串中有“_”),如果你想的话,我相信你可以将其转换成无法阅读的正则表达式:
/* floats: Follows ISO C89, except that we allow underscores */
let decimal_string = digit (underscore? digit) *
let hexadecimal_string = hexdigit (underscore? hexdigit) *
let decimal_fractional_constant =
decimal_string '.' decimal_string?
| '.' decimal_string
let hexadecimal_fractional_constant =
("0x" |"0X")
(hexadecimal_string '.' hexadecimal_string?
| '.' hexadecimal_string)
let decimal_exponent = ('E'|'e') ('+'|'-')? decimal_string
let binary_exponent = ('P'|'p') ('+'|'-')? decimal_string
let floating_suffix = 'L' | 'l' | 'F' | 'f' | 'D' | 'd'
let floating_literal =
(
decimal_fractional_constant decimal_exponent? |
hexadecimal_fractional_constant binary_exponent?
)
floating_suffix?
C格式是为编程语言而设计的,而不是数据,因此它可能支持您的输入不需要的功能。
[\d.]+
分解为\d+\.\d+
,以防止误匹配。如果小数点前和/或后不要求数字,则使用\d*
。 - moinudin5.5.5.5.5.5.5.5.5.5.5.5.5
。 - Martin York