javascript - 需要帮助从 JavaScript 中的字符串中提取数字
问题描述
我需要一个坚如磐石的 RegExp 来尝试解决 Raphael.jsparseStringPath
处理有关 Arc 路径命令和可能的其他命令的一些问题(SnapSVG 也继承了该问题)。你看,arcTo
path 命令接受 7 个坐标和设置,但是某些字符串可能由于极端优化而格式错误,并且浏览器不会标记它们,而是正确呈现它们。在此处查看Raphael.js 演示。
看看这个例子,我使用 Raphael.js 的 RegExp 和一个非常简单的例子,我自己的 RegExp 叫做incorrectReg
,试图将字符串分解000
为 [ 0
, 0
, 0
] 或011
[ 0
, 1
, 1
]。
let spaces = "\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029",
pathValues = new RegExp(`(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[${spaces}]*,?[${spaces}]*`, `ig`),
incorectReg = new RegExp(`([${spaces}]*0(?=[a-z0-9])|([${spaces}]\\0)*0(?=[a-z0-9]*))`, `ig`); // THIS ONE
function action(){
let input = document.getElementById('input'),
output = document.getElementById('output'),
pathValue = input.getAttribute('d'),
segments = pathValue.replace(/([a-z])/gi,'|$1').split('|').filter(x=>x.trim()),
pathArray = []
segments.map(x=>{
let pathCommand = x[0],
pathParams = x.replace(pathCommand,'').trim()
pathArray.push( [pathCommand].concat(
pathParams.replace(',',' ')
.replace(pathValues,' $1 ')
.replace(incorectReg,'$1 ')
.split(' '))
.filter(x=>x)
);
})
output.setAttribute('d',pathArray.map(x=>x.join(' ')).join(''))
console.table(pathArray)
}
svg {max-width:49%}
<button onclick="action()">Extract</button>
<hr>
<svg viewBox="0 0 16 16">
<path id="input" d="M2,0a2 2 0 00,-2 2a2 2 0 002 2a.5.5 0 011 0z" stroke="red" stroke-width="1px" fill="none"></path>
</svg>
<svg viewBox="0 0 16 16">
<path id="output" d="M0 0" stroke="green" stroke-width="1" fill="none"></path>
</svg>
正如您在浏览器控制台中看到的那样,我们已经求解了000
组(这显然不是一个有效的数字、布尔值或任何特定的值),我们只需要求解011
and 11
,所有这些组实际上都是一串布尔值。
同样,arcTo
路径命令适用于
arcTo -> ['A', rx, ry, xAxisRotation, largeArcFlag, sweepFlag, x, y]
// str, float, float, float, boolean (0|1), boolean (0|1), float, float
我需要一个更好的incorrectReg
RegExp 和一个解决方案组合来正确处理 mainarcTo
和其他类似情况。接受任何建议。
谢谢
解决方案
根据 OP 下面的讨论,我建议不使用正则表达式,而是使用适当的解析器(或词法分析器或标记器或如何正确调用它)。
你可以
- 编写自己的解析器(很好的练习)
- 使用现有的东西,例如我已成功尝试 svg-path-parser。
我什至不确定是否可以创建这样的“超级”正则表达式。无论如何,您可以在解析过程中使用“子”正则表达式:-)
推荐阅读
- angular - 如何防止在Angular中双击?
- javascript - 为什么我从谷歌脚本中的 indexOf 操作中得到不一致的结果,看起来是完全相同的输入?
- java - Spring Security 将过滤器应用于不安全的 URL
- javascript - Angular-chart.js 空白 div
- c# - .Net Core 在不同操作系统上查找可用磁盘空间
- r - is.numeric 如何在循环中工作?
- reactjs - 无法使 React Native 登录屏幕类似于图像布局
- javascript - 无法找出 HTML cURL 到 RestAPI 中正文部分的 JavaScript json
- python - Python - 将字典值列表减少为更小的列表
- android - 我可以在运行 AR 活动时更新 .sfb 文件吗?