Сделайте группы RegEx для разделения строки на столбцы - PullRequest
0 голосов
/ 28 мая 2020

У меня возникли проблемы с созданием некоторых регулярных выражений на основе запятых. В следующей структуре первые 19 столбцов должны быть разделены только запятыми, следующие 3 столбца имеют { }, но внутри этих скобок у меня может быть больше скобок (это «блок сценария»). Итак, для последних 3 я хочу, чтобы все было внутри ,{}

Это структура

ID,AegisName,Name,Type,Buy,Sell,Weight,ATK[:MATK],DEF,Range,Slots,Job,Class,Gender,Loc,wLV,eLV[:maxLevel],Refineable,View,{ Script },{ OnEquip_Script },{ OnUnequip_Script }

Например, с этим

1624,Lich_Bone_Wand,Lich's Bone Wand,5,20,,800,60:170,,1,2,0x00018314,18,2,2,3,70,1,10,{ bonus bInt,1; bonus bDex,1; bonus bAtkEle,Ele_Undead; .@r = getrefine(); bonus3 bAutoSpellWhenHit,"NPC_WIDECURSE",5,10+.@r; if(.@r>=9){ bonus bMatkRate,3; bonus bMaxSP,300; } },{},{}

Я нашел это ([^\,]*),"x(19)."(\{.*\}),"x(2)."(\{.*\}), но это Perl, и я не смог перевести на JavaScript. Я вижу, что если я объединю (\{.*\}) три раза (например, этот (\{.*\}),(\{.*\}),(\{.*\}), он даст мне последние 3 столбца, а этот ([^\,]*), даст мне правильное разделение первых столбцов, но также будет мешать последним, поэтому я попытался "ограничить" его до первых 19 случаев, но если я сделаю ([^\,]*),{19}, это не сработает

Как мне сделать sh это?

1 Ответ

1 голос
/ 28 мая 2020

Существует несколько способов sh этого, используя комбинацию замены и разделения:

  1. временно заменить запятые в {...}, разделить запятыми, восстановить запятые в каждом массиве элемент
  2. разделить запятыми, затем объединить элементы массива от первого вхождения { до последнего вхождения }, отслеживая вложенность
  3. , сделать разделение с отрицательным просмотром вперед, чтобы избежать разделения на запятых внутри {...}

Вот пример для первого варианта, где мы временно заменяем запятые внутри {...}:

function properSplit(line) {
    return line
    .replace(/(\{[^,]*,.*?\})(?=,)/g, function(m, p1) {
        return p1.replace(/,/g, '\x01');
    })
    .split(/,/)
    .map(function(item) {
        return item.replace(/\x01/g, ',');
    });
}

var str = "1624,Lich_Bone_Wand,Lich's Bone Wand,5,20,,800,60:170,,1,2,0x00018314,18,2,2,3,70,1,10,{ bonus bInt,1; bonus bDex,1; bonus bAtkEle,Ele_Undead; .@r = getrefine(); bonus3 bAutoSpellWhenHit,\"NPC_WIDECURSE\",5,10+.@r; if(.@r>=9){ bonus bMatkRate,3; bonus bMaxSP,300; } },{},{}";
console.log(JSON.stringify(properSplit(str), null, ' '));

Вывод:

[
 "1624",
 "Lich_Bone_Wand",
 "Lich's Bone Wand",
 "5",
 "20",
 "",
 "800",
 "60:170",
 "",
 "1",
 "2",
 "0x00018314",
 "18",
 "2",
 "2",
 "3",
 "70",
 "1",
 "10",
 "{ bonus bInt,1; bonus bDex,1; bonus bAtkEle,Ele_Undead; .@r = getrefine(); bonus3 bAutoSpellWhenHit,\"NPC_WIDECURSE\",5,10+.@r; if(.@r>=9){ bonus bMatkRate,3; bonus bMaxSP,300; } }",
 "{}",
 "{}"
]

Пояснение:

  • Первый replace() заменяет запятые в {...} непечатаемым символом '\x01'. Он сканирует не жадно к следующему шаблону },, где , - это положительный просмотр вперед
  • split() теперь пропускает запятые в {...}
  • map() восстановил непечатаемые символы до запятых
...