2013-07-24 64 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)");