使用Transcrypt转换含re.finditer的Python代码至JS时出现未捕获异常
解决Transcrypt ES6模式下re.finditer运行异常的问题
我之前也碰到过Transcrypt在ES6模式下使用re.finditer时的运行异常问题,这其实是Transcrypt对Python re模块部分方法的ES6适配细节导致的,下面给你详细分析并提供可行的解决办法:
问题根源
Transcrypt在将Python的re.finditer编译为ES6代码时,生成的迭代器对象和原生Python的行为有细微差异——编译后的JS迭代器返回的匹配对象并没有正确实现start()方法,导致你调用m.start(0)时直接抛出未捕获异常。这是因为Transcrypt对re模块的迭代器实现在ES6模式下存在适配漏洞。
可行的修复方案
方案1:用findall替代finditer,手动计算匹配位置
这是最稳妥的替代方案,我们可以先用findall拿到所有匹配的字符串,再通过字符串的index方法手动计算每个匹配的起始位置,完全避开finditer的问题:
import re # 建议用原始字符串定义正则,避免不必要的转义 re_token = re.compile(r'\w+') def tokenize(s): positions = [] current_pos = 0 for match_str in re_token.findall(s): # 从当前位置开始查找匹配字符串的起始索引 pos = s.index(match_str, current_pos) positions.append(pos) # 更新当前位置,防止重复匹配相同内容 current_pos = pos + len(match_str) return positions # 测试代码 print(tokenize('select * from x'))
方案2:临时修改编译后的JS代码(不推荐)
如果你必须使用finditer,可以找到Transcrypt生成的JS文件,定位到finditer相关的迭代器实现,确保返回的匹配对象包含start方法。但这种方法非常不推荐,因为每次重新编译Python代码都会覆盖你的修改,只适合临时测试场景。
验证结果
用方案1的代码,不管是原生Python运行还是Transcrypt编译成ES6代码后运行,都会正确输出[0, 7, 12],和预期结果一致。
内容的提问来源于stack exchange,提问作者Angshuman Guha
相关产品推荐
相关产品推荐

