Confluence wiki markup-определение типа строк таблицы с помощью Regex

В слиянии wiki v6.0 существует два различных типа таблиц.

Поэтому я борюсь с определением типа таблицы по первой строке
(Я разделяю таблицу на строки путем обнаружения новой строки с regex, как это new Regex(@"(|(rn|r|n)(.*?)|)+");и разделить с помощьюMatches, но тем не менее)

Строка таблицы может выглядеть как:

что если его заголовок

/ / Заголовок 1 / / Заголовок 2 / / Заголовок 3 ||

что если его обычная строка

/ cell A1 / cell A2 / cell A3 |

и что если его вертикальная строка таблицы

/ / Заголовок / ячейка B2 / ячейка B3 |

Я пытался использовать такое выражение^(||.*?|), но обнаружил, что оно работает и для заголовков.

После того, как я попытался использовать этот из^(||.*?||)-за функции разметки заголовка, но это не помогает сказать, если его обычная строка

Так можно ли добиться определения типа строки или, по крайней мере, сказать, является ли она вертикальной строкой с использованием Regex?

Или лучше написать что-то, что будет обрабатывать строки шаг за шагом?

1 ответ

  1. Написал его без использования regex и в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();