首页 > 解决方案 > 需要帮助从 JavaScript 中的字符串中提取数字

问题描述

我需要一个坚如磐石的 RegExp 来尝试解决 Raphael.jsparseStringPath处理有关 Arc 路径命令和可能的其他命令的一些问题(SnapSVG 也继承了该问题)。你看,arcTopath 命令接受 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组(这显然不是一个有效的数字、布尔值或任何特定的值),我们只需要求解011and 11,所有这些组实际上都是一串布尔值。

同样,arcTo路径命令适用于

arcTo -> ['A', rx,    ry,    xAxisRotation, largeArcFlag,  sweepFlag,     x,     y]
       // str, float, float, float,         boolean (0|1), boolean (0|1), float, float

我需要一个更好的incorrectRegRegExp 和一个解决方案组合来正确处理 mainarcTo和其他类似情况。接受任何建议。

谢谢

标签: javascriptregexsvgraphaelsnap.svg

解决方案


根据 OP 下面的讨论,我建议不使用正则表达式,而是使用适当的解析器(或词法分析器或标记器或如何正确调用它)。

你可以

  • 编写自己的解析器(很好的练习)
  • 使用现有的东西,例如我已成功尝试 svg-path-parser

我什至不确定是否可以创建这样的“超级”正则表达式。无论如何,您可以在解析过程中使用“子”正则表达式:-)


推荐阅读