没有使用正则表达式和 in 就写了javascript
,看起来像这样
简单的字符串扫描器
var Scanner = (function(){
function Scanner(text){
this.currentString = text.split('');
this.position = 0;
this.errorList = [];
this.getChar = function(){
var me = this,
pos = me.position,
string = me.currentString,
stringLength = string.length;
if(pos < stringLength){
return string[pos];
}
return -1;
};
this.nextChar = function(){
var me = this,
pos = me.position,
string = me.currentString,
stringLength = string.length;
if(pos < stringLength){
me.position++;
return;
}
me.error("EOL reached");
};
this.error = function(errorMsg){
var me = this,
error = "Error at position " + me.position +"\nMessage: "+errorMsg+".\n";
errors = me.errorList;
errors.push[error];
};
return this;
};
return Scanner;
})();
简单的解析器
/**
LINE ::= { CELL }
CELL ::= '|' CELL1
CELL1 ::= HEADER_CELL | REGULAR_CELL
HEADER_CELL ::= '|' TEXT
REGULAR_CELL ::= TEXT
*/
function RowParser(){
this.scanner = {};
this.rawText = "";
this.cellsData = [];
return this;
};
RowParser.prototype = {
parseRow: function(row){
var me = this;
me.scanner = new Scanner(row);
me.rawText = row;
me.cellsData = [];
me.proceedNext();
},
proceedNext: function(){
var me = this,
scanner = me.scanner;
while(scanner.getChar() === '|'){
me.proceedCell();
}
if (scanner.getChar() !== -1)
{
scanner.error("EOL expected, "+ scanner.getChar() +" got");
}
return;
},
proceedCell: function(){
var me = this,
scanner = me.scanner;
if(scanner.getChar() === '|'){
scanner.nextChar();
me.proceedHeaderCell();
}
},
proceedHeaderCell: function(){
var me = this,
scanner = me.scanner;
if(scanner.getChar() === '|'){
me.onHeaderCell();
} else {
me.onRegularCell();
}
},
onHeaderCell: function(){
var me = this,
scanner = me.scanner,
cellType = TableCellType.info,
cellData = {
type: cellType.Header
}
if(scanner.getChar() === '|'){
scanner.nextChar();
me.proceedInnerText(cellType.Header);
}else{
scanner.error("Expected '|' got "+ currentChar +".");
}
},
onRegularCell:function(){
var me = this,
scanner = me.scanner,
cellType = TableCellType.info;
me.proceedInnerText(cellType.Regular);
},
proceedInnerText: function(cellType){
var me = this,
scanner = me.scanner,
typeData = TableCellType.getValueById(cellType),
innerText = [];
while(scanner.getChar() !== '|' && scanner.getChar() !== -1){
innerText.push(scanner.getChar());
scanner.nextChar();
}
me.cellsData.push({
typeId: typeData.id,
type: typeData.name,
text: innerText.join("")
});
me.proceedNext();
},
getRowData: function(){
var me = this,
scanner = me.scanner,
data = me.cellsData,
emptyCell;
//Proceed cell data
//if there no empty cell in the end - means no close tag
var filteredData = data.filter(function(el){
return el.text.length !== 0;
});
if(filteredData.length === data.length){
scanner.error("No close tag at row "+ me.rawText +".");
return;
}
for (var i = 0; i < filteredData.length; i++) {
filteredData[i].text = filteredData[i].text.trim();
}
return filteredData;
}
};
CellTypeEnum
上文提到的
var TableCellType = {
info:{
Regular: 10,
Header: 20
},
data:[
{
id: 10,
name: "regular"
},
{
id: 20,
name: "header"
}
],
getValueById: function(id){
var me = this,
data = me.data,
result = data.filter(function(el){
return el.id === id;
});
return result[0];
}
}
用法:
var rowParser = new RowParser();
var row = "||AAA||BBB||CCC||\n|Hi|all|people!|";
rowParser.parseRow(row);
var result = rowParser.getRowData();