什么是正确将SVG'd'属性分割为标记的正则表达式?

Oct*_*pus 5 javascript regex

我试图将dsvg文件中的路径标记上的属性拆分为标记.

这个比较容易:

d = "M 2 -12 C 5 15 21 19 27 -2 C 17 12 -3 40 5 7"
tokens = d.split(/[\s,]/)
Run Code Online (Sandbox Code Playgroud)

但这也是一个有效的d属性:

d = "M2-12C5,15,21,19,27-2C17,12-3,40,5,7"
Run Code Online (Sandbox Code Playgroud)

棘手的部分是字母,数字不再分开,负数只使用负号作为分隔符.如何创建处理此问题的正则表达式?

规则似乎是:

  • 只要有空格或逗号就分开
  • 从字母中分割数字(并用数字保持" - ")

我知道我可以使用环视,例如:

tokens = pathdef.split(/(?<=\d)(?=\D)|(?<=\D)(?=\d)/)
Run Code Online (Sandbox Code Playgroud)

我在制作单个正则表达式时也遇到了麻烦,这个正则表达式也会在减号上分开,并用数字保留减号.

上面的代码应该标记为如下:

[ 'M', '2', '-12', 'C', '5', '15', '21', '19', '27', '-2', 'C', '17', '12', '-3', '40', '5', '7' ]
Run Code Online (Sandbox Code Playgroud)

ctw*_*els 5

简短的

不幸的是,JavaScript 不允许lookbehinds ,因此您的选择相当有限,并且下面“其他正则表达式引擎”部分中的正则表达式对您不起作用(尽管它可以与其他一些正则表达式引擎一起使用)。

其他正则表达式引擎

注意:本节中的正则表达式(其他正则表达式引擎)在 Javascript 中不起作用。请参阅代码部分中的 JavaScript 解决方案。

我认为用你原来的正则表达式你试图达到:

[, ]|(?<![, ])(?=-|(?<=[a-z])\d|(?<=\d)[a-z])
Run Code Online (Sandbox Code Playgroud)

此正则表达式允许您分割这些匹配项(,,或 后跟的位置-,或字母在数字前面的位置或数字在字母前面的位置)。


代码

[, ]|(?<![, ])(?=-|(?<=[a-z])\d|(?<=\d)[a-z])
Run Code Online (Sandbox Code Playgroud)


解释

  • -?\d+(?:\.\d+)?|[a-z]匹配以下任意一项
    • -?\d+(?:\.\d+)?
      • -?从字面上匹配-零次或一次
        • (?:\d*\.)?匹配以下零次或一次
          • \d*匹配任意数量的数字
          • \.匹配文字点
      • \d+匹配一位或多位数字
    • [a-z]匹配范围内的任何字符a-z(任何小写字母字符 - 由于i使用了修饰符,这也匹配这些字母的大写变体)

我添加是(?:\d*\.)?因为(据我所知)SVGd属性中可以有十进制数值。

注意\d+(?:\.\d+)?:更改了to的原始正则表达式部分(?:\d*\.)?\d+,以便捕获没有整数部分的数字,例如.5@Thomas 请参阅问题下面的评论)。