специальное расщепление строк в Ruby - PullRequest
6 голосов
/ 04 марта 2010

Я пытаюсь найти лучший способ сделать это ...

Учитывая строку

s = "if someBool || x==1 && y!=22314" 

Я хотел бы использовать Ruby для разделения операторов и логических операторов.поэтому я хотел бы разделить это на

["if","someBool","||","x","==","1","&&","y","!=","22314"]

Я мог бы использовать s.split (), но это разделяет только пробел в качестве разделителей ... но я бы хотел, чтобы x! = y было разделенотоже (это допустимые логические предложения, между ними просто нет места для хорошей читаемости).Конечно, самый простой способ - потребовать от пользователя поставить пробел между логическим оператором и переменными, но есть ли другой способ сделать это?

Ответы [ 4 ]

4 голосов
/ 04 марта 2010

Разделить на пробел или границу слова:

s = "if someBool || x==1 && y!=22314"
a = s.split( /\s+|\b/ );
p a

Выход:

["if", "someBool", "||", "x", "==", "1", "&&", "y", "!=", "22314"]
2 голосов
/ 04 марта 2010

Мое эмпирическое правило: используйте split, если вы знаете, что выбрасывать (разделители), используйте регулярное выражение, если вы знаете, что оставить. В этом случае вы знаете, что хранить (токены), поэтому:

s.scan(/ \w+ | (?: \s|\b )(?: \|\| | && | [=!]= )(?: \s|\b ) /x)
# => ["if", "someBool", "||", "x", "==", "1", "&&", "y", "!=", "22314"]

(?: \s|\b ) «разделители» предназначены для предотвращения совпадения ваших токенов (например, ==) с тем, что вам не нужно (например, !==)

1 голос
/ 04 марта 2010

Примерно так работает:

s = "12&&32 || 90==12 !=67"
a = s.split(/ |(\|\|)|(&&)|(!=)|(==)/)
a.delete("")
p a

По какой-то причине "" осталось в массиве, строка удаления исправила это.

1 голос
/ 04 марта 2010

Вы можете получить split для разделения на что угодно, включая регулярные выражения. Что-то вроде:

s.split( /\s|==|!=/ )

... может быть начало.

Отказ от ответственности: regexen заставляет мою голову болеть. Я проверил это сейчас, и оно работает против вашего примера.


ОБНОВЛЕНИЕ: Нет, это не так. split всегда пропускает то, что разделяет, поэтому приведенный выше код теряет == и! = из вашего примера. (Код Monoceres работает отлично.)

Но по какой-то причине, если вы заключите разделенное выражение в регулярное выражение в скобках, оно сохранит эту вещь в массиве ответов, а не просто разделит ее. Я не знаю, является ли это ошибкой, особенностью или каким-то умным дизайном, который я не оценил должным образом.

Так что на самом деле вам нужно:

s.split( /\s|(==)|(!=)/ )

Но это вряд ли код, который объясняет сам себя. И насколько я знаю, это не работает в 1.9.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...