2024-09-30 02:30:52 发布
网友
如何编写一个Python函数来模拟strtod,它同时返回转换后的数字和下一个字符的位置?
strtod
我不知道任何现有的函数可以做到这一点。在
但是,使用正则表达式编写一个非常容易:
import re # returns (float,endpos) def strtod(s, pos): m = re.match(r'[+-]?\d*[.]?\d*(?:[eE][+-]?\d+)?', s[pos:]) if m.group(0) == '': raise ValueError('bad float: %s' % s[pos:]) return float(m.group(0)), pos + m.end() print strtod('(a+2.0)/1e-1', 3) print strtod('(a+2.0)/1e-1', 8)
一个更好的整体方法可能是构建一个lexical scanner,它首先将表达式标记化,然后使用一系列标记,而不是直接使用字符串(或者确实是全力以赴地构建一个yacc风格的解析器)。在
您可以创建一个简单的C strtod包装:
#include <stdlib.h> double strtod_wrap(const char *nptr, char **endptr) { return strtod(nptr, endptr); }
编译时使用:
(如果使用64位Python,编译器也必须是64位的)
并使用python中的ctypes调用它(linux:在lib目标中将.dll改为{},在下面的代码中,这在Windows上进行了测试):
ctypes
.dll
import ctypes _strtod = ctypes.CDLL('libstrtod.dll') _strtod.strtod_wrap.argtypes = (ctypes.c_char_p, ctypes.POINTER(ctypes.c_char_p)) _strtod.strtod_wrap.restype = ctypes.c_double def strtod(s): p = ctypes.c_char_p(0) s = ctypes.create_string_buffer(s.encode('utf-8')) result = _strtod.strtod_wrap(s, ctypes.byref(p)) return result,ctypes.string_at(p) print(strtod("12.5hello"))
印刷品:
(12.5, b'hello')
(这并不像看上去那么难,因为我10分钟前就学会了怎么做)
关于ctypes的有用问答
你自己分析这个数字。在
递归下降解析器对于这种输入非常容易。 首先写一个语法:
float ::= ipart ('.' fpart)* ('e' exp)* ipart ::= digit+ fpart ::= digit+ exp ::= ('+'|'-') digit+ digit = ['0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9']
现在把这个语法转换成函数应该很简单。。。在
我不知道任何现有的函数可以做到这一点。在
但是,使用正则表达式编写一个非常容易:
一个更好的整体方法可能是构建一个lexical scanner,它首先将表达式标记化,然后使用一系列标记,而不是直接使用字符串(或者确实是全力以赴地构建一个yacc风格的解析器)。在
您可以创建一个简单的C
strtod
包装:编译时使用:
^{pr2}$(如果使用64位Python,编译器也必须是64位的)
并使用python中的},在下面的代码中,这在Windows上进行了测试):
ctypes
调用它(linux:在lib目标中将.dll
改为{印刷品:
(这并不像看上去那么难,因为我10分钟前就学会了怎么做)
关于
ctypes
的有用问答你自己分析这个数字。在
递归下降解析器对于这种输入非常容易。 首先写一个语法:
现在把这个语法转换成函数应该很简单。。。在
相关问题 更多 >
编程相关推荐