2010-03-04 85 views
6

我试图找出做到这一点的最好办法...特殊字符串分割在Ruby中

给出一个字符串

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

我想用Ruby单独的语句和布尔运算符..所以我想这个分成

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

我可以使用s.split(),但这个空间只拆分为delimeters..but我想X!=要过分裂ÿ (他们是有效的布尔句子,他们只是没有空间之间为了良好的可读性)。当然最简单的方法是要求用户在布尔运算符和变量之间放置空格,但是有没有其他方法可以做到这一点?

回答

4

分割上的空白或一个单词边界:

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

输出:

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

是的,那对我来说。尼斯。 – Shadowfirebird 2010-03-04 14:24:53

1

你可以拆分任何你想要的,包括正则表达式。例如:

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

...可能是一个开始。

声明:regexen让我的头受伤。我现在已经测试过了,它对你的例子有效。


更新:不,它没有。拆分总是跳过它分割的内容,所以上面的代码在你的例子中失去了==和!=。 (Monoceres的代码工作正常。)

但由于某些原因,如果将括号中的分词放在括号内的正则表达式中,它会将答案保留在答案数组中,而不仅仅是将其分解。我不知道这是一个错误,一个功能,还是一些设计巧妙,我不明白。

所以实际上你需要:

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

但是,这是很难的代码解释本身。据我所知,它在1.9中不起作用。

1

事情是这样工作的:

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

出于某种原因,“”留在阵中,删除线固定的。

2

我的经验法则:如果您知道要丢弃什么(分隔符),请使用split,如果您知道要保留什么,请使用正则表达式。在这种情况下,你知道什么样保持(令牌),所以:

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

(?: \s|\b)“分隔符”是防止您的令牌(如==)从匹配你不想要的东西(如!==

+0

我认为扫描更像C,可能更有效,我也想坚持下去。 – Jose 2010-03-04 14:02:13

+1

@jocapco,如果“c-like”很重要,为什么Ruby? – 2010-03-04 14:10:58

+0

其不重要,它只是好看:)红宝石,因为我在做什么需要用户知道很少,做了很多..使用脚本语言像红宝石将是优选的。我只是还在做小规模的东西。 – Jose 2010-03-04 14:48:55