Лучший способ разобрать список номеров - PullRequest
0 голосов
/ 13 сентября 2011

У меня проблема в том, что мне нужно обработать список чисел, который будет в английском предложении. Может быть в следующих форматах:

пункты 1, 2 и 3

пункты со 2 по 5

пункты с 1 по 20

пунктов 4 или 8

Мой первоначальный инстинкт - написать простой конечный автомат для его анализа, но мне было интересно, есть ли какой-нибудь лучший (более простой) способ, такой как, возможно, какое-то регулярное выражение. Любой совет?

Ответы [ 3 ]

1 голос
/ 13 сентября 2011

Если у вас есть C ++ 11, следующий синтаксический анализатор (AX) проанализирует все ваши форматы (я его не тестировал):

unsigned i;
auto num = axe::r_unsigned(i);
auto space = axe::r_any(" \t");
auto format1 = num % (*space & ',' & *space) & ~("and" & +space & num);
auto format2 = num & +space & "through" & +space & num;
auto format3 = num & +space & "to" & +space & num;
auto format4 = num & +space & "or" & +space & num;
auto format = "items" & +space & (format1 | format2 | format3 | format4);

Если у вас нет C ++ 11, вы можете написать похожий парсер на C ++, используя boost :: spirit . Писать и отлаживать такой анализатор проще и короче, чем с помощью регулярных выражений, а также вы получаете большую гибкость при создании правил синтаксического анализа и семантических действий.

0 голосов
/ 13 сентября 2011

Кажется очень простым написать синтаксический анализатор для этих строк, используя регулярное выражение для каждого случая или отдельное выражение с альтернативой для каждого. Вам нужно использовать что-то вроде \d+, чтобы соответствовать числам. Я бы также сгруппировал каждый набор похожих комбинаторов (например, «and» / «or» и «to» / «through») в единую альтернативу, чтобы упростить обработку результатов.

0 голосов
/ 13 сентября 2011

Если вы подключены к Java, используйте функцию регулярного выражения.

http://download.oracle.com/javase/tutorial/essential/regex/

Но если это не так, сценарий sed лучше всего подходит для простой обработки текста.

sed 's/\d{1,} /\1 /g' < file.txt
...