2013-07-24 30 views
4

假设我们有一个SVG变换字符串:解析SVG变换属性用JavaScript

transform = "translate(6,5),scale(3,3)"; 

有没有我们可以用它来解析成有用的东西漂亮的正则表达式的功能?

+0

能告诉你,如果你已经尝试的东西吗? – icedwater

+0

我不能做正则表达式@ icedwater-即时寻找一些人的帮助 – Yarin

+0

如果你知道你需要正则表达式,那么你知道你期望分析什么......然后这是一个寻找正确的语法的问题一个正则表达式。在这里,我将谷歌的JavaScript正则表达式,然后开始。 – icedwater

回答

10

这里的代码一个漂亮的小片段,可能会得到你所需要的,它应该涵盖大多数情况下如果你打算解析字符串有不同数目的参数:

function parse (a) 
{ 
    var b={}; 
    for (var i in a = a.match(/(\w+\((\-?\d+\.?\d*e?\-?\d*,?)+\))+/g)) 
    { 
     var c = a[i].match(/[\w\.\-]+/g); 
     b[c.shift()] = c; 
    } 
    return b; 
} 

运行此

parse('translate(6,5),scale(3,3.5),a(1,1),b(2,23,-34),c(300)'); 

会导致这样的:

{ 
    translate: [ '6', '5' ], 
    scale: [ '3', '3.5' ], 
    a: [ '1', '1' ], 
    b: [ '2', '23', '-34' ], 
    c: [ '300' ] 
} 
+0

@ chernjie-获胜!美丽.. – Yarin

+1

我更新了正则表达式来处理数字小数FYI ... – Yarin

+0

很酷,看起来不错! – chernjie

3
var transform = "translate(6,5),scale(3,3)"; 
var translate = /translate\(\s*([^\s,)]+)[ ,]([^\s,)]+)/.exec(transform); 
var translateX = translate[1] 
var translateY = translate[2] 
var scale = /scale\(\s*([^\s,)]+)[ ,]([^\s,)]+)/.exec(transform); 
var scaleX = translate[1] 
var scaleY = translate[2] 

transformValues = {translate:{x:translateX,y:translateY}, 
scale:{x:scaleX,y:scaleY}} 

相当严重,但@icedwater是让我做所有自己,所以...

+0

好吧,你打败了我 - 你可以编辑它到上面的问题。我也需要查看JS正则表达式,所以。 – icedwater

+0

哈,是啊非常感谢您抽出时间 - 欢呼 – Yarin

1

我要在此一刺,说你希望它被解析成含有一个JSON对象工作每个属性作为列表中的条目。这是迄今为止我来最接近:

function listIntoJSON(theTransformInQuestion) { 

    // let's work with transform = "translate(6,5),scale(3,3)" as specified. 
    var result = []; // empty list to be returned 
    var splitList = theTransformInQuestion.split(/\W/); 
    // now splitList is ["translate", "6", "5", "", "scale", "3", "3", ""] 

    for (var t = 0; t < splitList.length; t += 4) { 
     var op = {}; 
     op.name = splitList[t]; 
     op.x = splitList[t + 1]; 
     op.y = splitList[t + 2]; 
     result.push(op); // add op to the result list 
    } 
    return result; 
} 

将于

transform = "translate(6,5),scale(3,3)"; 

,并返回

[ 
    {name: "translate", x: "6", y: "5"}, 
    {name: "scale", x: "3", y: "3"} 
] 

,应该对任何数量的变换工作。黑客的位,但它现在会做。

+0

如果您可以得到那种嗡嗡声,我很乐意看到它 - 谢谢 – Yarin

+0

它比我想象的要花费更长的时间,提醒我稍后再工作;) – icedwater

+0

我的东西看起来不错,当我学习如何将东西转储到对象而不是使用列表时,我可能会再次处理这个问题。随意改善它:) – icedwater

2

从@chernjie改编的解决方案:

function parse_transform(a) { 
    var b = {}; 
    for (var i in a = a.match(/(\w+)\(([^,)]+),?([^)]+)?\)/gi)) { 
     var c = a[i].match(/[\w\.\-]+/g); 
     b[c.shift()] = c; 
    } 
    return b; 
} 
+1

谢谢!在这里工作! – mrlew

1

假设您在浏览器中运行,还可以使用SVG DOM来解析和解码变换字符串。

var svgns = "http://www.w3.org/2000/svg"; 
 

 
function getTransformList(transformStr) 
 
{ 
 
    // Create a fake <rect> element to set the transform to 
 
    var rect = document.createElementNS(svgns, "rect"); 
 
    rect.setAttribute("transform", transformStr); 
 
    // Use the DOM to get the list of decoded transforms 
 
    dumpTransform(rect.transform.baseVal); 
 
} 
 

 
function dumpTransform(transformList) 
 
{ 
 
    for (var i=0; i<transformList.length; i++) 
 
    { 
 
    var transform = transformList[i]; 
 
    var m = transform.matrix; 
 
    switch (transform.type) 
 
    { 
 
     case 2: 
 
     console.log("translate("+m.e+","+m.f+")"); 
 
     break; 
 
     case 3: 
 
     console.log("scale("+m.a+","+m.d+")"); 
 
     break; 
 
     case 4: 
 
     console.log("rotate("+transform.angle+")"); 
 
     // TODO need to also handle rotate(angle, x, y) form 
 
     break; 
 
     case 5: 
 
     // TODO skewX() 
 
     break; 
 
     case 6: 
 
     // TODO skewY(() 
 
     break; 
 
     case 1: 
 
     default: 
 
     console.log("matrix("+m.a+","+m.b+","+m.c+","+m.d+","+m.e+","+m.f+")"); 
 
     break; 
 
    } 
 
    } 
 
} 
 

 
getTransformList("translate(6,5),scale(3,3)");