2016-06-21 2 views
0

Я пытаюсь взять строку, которая может выглядеть как одно из следующих действий:Интерпретировать строку как координаты в JavaScript с помощью Regex

  • авианосец размещены на A1, A2, A3, A4, A5; броненосец на B6, C6, D6; и подводную лодку в H3, I3, J3;
  • A: A1-A5; B: B6-D6; S: H3-J3
  • A (A1-A5); В (В6-D6); S (H3-J3);
  • B (B6-D6), S (H3-J3), A (A1-A5)

Я хочу взять координаты каждого судна и поместить их в 2D массив. Я понимаю, как использовать регулярные выражения, но у меня возникают проблемы с преобразованием его в координаты, которые я могу легко использовать для размещения. Какие-либо предложения?

+0

Вы почти наверняка не хотите регулярное выражение: если вы анализируете координаты с регулярным выражением, вы получите непроверенные координаты и ошибку регулярного выражения. Это достаточно просто, что расщепление на разделителях, а затем захват пар буквенных чисел должен сделать это. Если вы хотите сходить с ума, что-то вроде pegjs может написать полномасштабный синтаксический анализатор. – ssube

+0

Возможно, вам захочется разбить его на ';' сначала, а затем искать ':' или если вы знаете, что есть круглые скобки, которые вы можете сопоставить для этого. Но эта первая строка выглядит как-то беспорядочно ... –

+0

Как я могу заставить ее работать для каждой версии строки? – tittimous

ответ

0

Я точно не знаю, какой окончательный формат вы притворяетесь. Я просто быстро разборелся просто для удовольствия. Вы можете попробовать улучшить здесь

function parseCoord(coord){ 
    return [coord[0].codePointAt() - 65, ~~coord[1]]; 
} 

const yourString = "A:A1-A5;B:B6-D6; S:H3-J3" 

const output = yourString 
    .split(';') 
    .map(x => x.match(/^\s?([BSA])[(:]?([A-Z]\d)-([A-Z]\d)\)?$/)) 
    .filter(x => !!x) 
    .map(([, type, ...coords]) => [type, ...coords.map(parseCoord)]) 
    .reduce((obj, [type, ...coords]) => Object.assign({ [type]: coords}, obj), {}); 

Что я могу получить в качестве выходного?

{ 
    S: [ [ 7, 3 ], [ 9, 3 ] ], 
    B: [ [ 1, 6 ], [ 3, 6 ] ], 
    A: [ [ 0, 1 ], [ 0, 5 ] ] 
} 

я мог бы улучшить здесь, но я действительно не знаю, что вам нужно как конечный результат

Если вы хотите «A», чтобы быть 1 вместо нуля просто поменять 65 на 64 в функции parseCoord.

Вы также можете настроить регулярное выражение, чтобы принимать цифры выше 9, вместо того, чтобы сопоставлять одну цифру, такую ​​как /\d/, вы можете сопоставить 1 цифру и сделать вторую опцию, используя необязательный модификатор . Так что соответствующая группа хотела бы этого ([A-Z]\d\d?)

PS: Извините, если вы не используете синтаксис ES6, я использую его каждый день, и я не могу помочь себе.

EDIT: Регулярные выражения могут выглядеть страшно. Обычно у вас есть проблема, вы решаете ее с помощью регулярного выражения. Теперь у вас две проблемы.

Я попытаюсь объяснить регулярное выражение

/^\s?([BSA])[(:]?([A-Z]\d)-([A-Z]\d)\)?$/

^ Начало строки

\s? Существует опциональный пространство

([BSA]) Match буква B, S или А и захватить их

[(:]? Существует «(» или «:», но это дополнительный

([A-Z]\d) Матч письмо от А до Z, а затем цифры и захватить их

- Совпадение «-». Это необходимо, потому что нет?'

([A-Z]\d) Матч другой координате и захватить его

\)? Совпадение „)“, но это необязательно

$ конец строки

Надежда, что он надеется, в определенной степени.

+0

Синтаксис довольно странный для меня, где именно результат, который вы предоставили, был сохранен? – tittimous

+0

Я не сохранял его. Просто отредактировал сообщение и добавил выходную переменную, называемую «output». Вы можете протестировать код в браузере модели или версии node.js 6. Если вы используете более старую версию, вам нужно перевести код с помощью babel или любого другого транспилятора ES6 – andre

Смежные вопросы