我正在尝试将 svg 文件中路径标签上的d
属性拆分为标记。
这个相对容易:
d = "M 2 -12 C 5 15 21 19 27 -2 C 17 12 -3 40 5 7"
tokens = d.split(/[s,]/)
但这也是一个有效的d
属性:
d = "M2-12C5,15,21,19,27-2C17,12-3,40,5,7"
棘手的部分是字母和数字不再分开,负数仅使用负号作为分隔符。如何创建处理此问题的正则表达式?
规则似乎是:
- 在有空格或逗号的地方拆分
- 将数字与字母分开(并将"-"与数字保持在一起)
我知道我可以使用环顾四周,例如:
tokens = pathdef.split(/(?<=d)(?=D)|(?<=D)(?=d)/)
我在形成一个正则表达式时遇到问题,该正则表达式也会在减号上拆分,并将减号与数字一起保留。
上面的代码应按如下方式标记:
[ 'M', '2', '-12', 'C', '5', '15', '21', '19', '27', '-2', 'C', '17', '12', '-3', '40', '5', '7' ]
简介
不幸的是,JavaScript 不允许回溯,所以你的选择相当有限,下面其他正则表达式引擎部分中的正则表达式对你不起作用(尽管它会与其他一些正则表达式引擎一起使用)。
其他正则表达式引擎
注意:本节中的正则表达式(其他正则表达式引擎)在 Javascript 中不起作用。请改为查看代码部分中的 JavaScript 解决方案。
我认为使用您的原始正则表达式,您正在尝试:
[, ]|(?<![, ])(?=-|(?<=[a-z])d|(?<=d)[a-z])
此正则表达式允许您拆分这些匹配项(,
或,或后跟
-?d+(?:.d+)?|[a-z]
的位置,或字母在数字之前的位置或数字在字母之前的位置)。
法典
var a = [
"M 2 -12 C 5 15 21 19 27 -2 C 17 12 -3 40 5 7",
"M2-12C5,15,21,19,27-2C17,12-3,40,5,7"
]
var r = /-?(?:d*.)?d+|[a-z]/gi
a.forEach(function(s){
console.log(s.match(r));
});
解释
-?d+(?:.d+)?
匹配以下任一条件-?
-
匹配(?:d*.)?
字面意思是零次或一次d*
匹配以下零次或一次.
匹配任意位数d+
匹配文字点
[a-z]
匹配一个或多个数字
a-z
匹配i
范围内的任何字符(任何小写字母字符 - 由于使用了修饰符(?:d*.)?
这也匹配这些字母的大写变体)
我添加了d
是因为(据我所知)您可以在 SVGd+(?:.d+)?
属性中使用十进制数字值。
注意:将(?:d*.)?d+
的原始正则表达式部分更改为.5
,以便根据@Thomas捕获没有整数部分的数字,例如CC_21(请参阅下面的评论问题)。
你可以去
-?d+|[A-Z]
在regex101.com 上观看演示。在这里,与其拆分,不如完全匹配它们:
matches = "M 2 -12 C 5 15 21 19 27 -2 C 17 12 -3 40 5 7".match(/-?d+|[A-Z]/g)
# matches holds the different tokens