的一般方法來分析,我喜歡經常採取如下:
- 循環通過文字,字符爲單位的完整塊。
- 如果您發現一個指示某個單元開始的字符,請調用專門的子函數來解析下一個字符。
- 在每個子功能中,如果找到某些字符,則調用其他子功能
- 當找到一個字符,表明該單元已結束時,從每個子功能返回。
這裏是一個小例子:
var text = "@func(arg1,arg2)"
function parse(text) {
var i, max_i, ch, funcRes;
for (i = 0, max_i = text.length; i < max_i; i++) {
ch = text.charAt(i);
if (ch === "@") {
funcRes = parseFunction(text, i + 1);
i = funcRes.index;
}
}
console.log(funcRes);
}
function parseFunction(text, i) {
var max_i, ch, name, argsRes;
name = [];
for (max_i = text.length; i < max_i; i++) {
ch = text.charAt(i);
if (ch === "(") {
argsRes = parseArguments(text, i + 1);
return {
name: name.join(""),
args: argsRes.arr,
index: argsRes.index
};
}
name.push(ch);
}
}
function parseArguments(text, i) {
var max_i, ch, args, arg;
arg = [];
args = [];
for (max_i = text.length; i < max_i; i++) {
ch = text.charAt(i);
if (ch === ",") {
args.push(arg.join(""));
arg = [];
continue;
} else if (ch === ")") {
args.push(arg.join(""));
return {
arr: args,
index: i
};
}
arg.push(ch);
}
}
FIDDLE
這個例子只是解析函數表達式,下面的語法 「@functionName(argumentName1,argumentName2,...)」 。總體思路是每次訪問一個字符一次,而不需要保存當前狀態,比如「hasSeenAtCharacter」或者「hasSeenOpeningParentheses」,當你解析大型結構時會變得非常混亂。
請注意,這是一個非常簡化的例子,它忽略了所有的錯誤處理和類似的東西,但我希望的總體思路可以看出。請注意,我並不是說你應該始終使用這種方法。這是一個非常普遍的方法,可以在很多場景中使用。但是,這並不意味着它不能與正則表達式相結合,例如,如果它在文本的某個部分比分析每個單獨的字符更有意義。
最後一句話:如果您將專用解析函數放入主解析函數中,您可以節省自己的麻煩,以便所有函數都可以訪問相同變量i
。
感謝您的協助。我將更多地研究regexps,並且看看我是否可以開始正確解析字符串。 –