2010-03-04 12 views
6

que estoy tratando de averiguar la mejor manera de hacer esto ...división cadena especial en Ruby

Dada una cadena

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

Me gustaría utilizar Ruby a separar las declaraciones y los operadores booleanos .. así que me gustaría dividir esto en

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

que podría utilizar s.split(), pero esto sólo fracturas con el espacio como delimeters..but me gustaría x! = y se divida demasiado (Son oraciones booleanas válidas, simplemente no tienen espacio en el medio para una buena legibilidad). Por supuesto, la forma más fácil es exigir al usuario que ponga espacio entre el operador booleano y las variables, pero ¿hay alguna otra forma de hacerlo?

Respuesta

4

Split, en un espacio en blanco o un límite de palabra:

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

salida:

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

Sí, eso lo hace por mí. Bonito. – Shadowfirebird

1

Puede dividir para dividir en cualquier cosa que desee, incluyendo una expresión regular. Algo como:

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

... podría ser un comienzo.

Descargo de responsabilidad: regexen me daña la cabeza. Lo he probado ahora y funciona en contra de tu ejemplo.


ACTUALIZACIÓN: No, no lo hace. split siempre omite aquello en lo que se divide, por lo que el código anterior pierde el == y! = de tu ejemplo. (El código de Monoceres funciona bien.)

Pero por alguna razón, si encierra el término dividido en la expresión regular entre paréntesis, lo mantiene en la matriz de respuestas en lugar de simplemente dividirlo. No sé si esto es un error, una característica o un poco de diseño inteligente que no aprecio correctamente.

Así que de hecho lo necesario:

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

pero esto no es código que explica a sí misma. Y por lo que sé, no funciona en 1.9.

1

Algo como esto funciona:

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

Por alguna razón "" permaneció en la matriz, la línea de borrado fijo que.

2

Mi regla general: use split si sabe qué tirar (los delimitadores), use una expresión regular si sabe qué guardar. En este caso, usted sabe lo que debe mantener (las fichas), por lo que:

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

Los (?: \s|\b) "delimitadores" son para evitar que sus fichas (por ejemplo ==) de igualar algo que no desee (por ejemplo !==)

+0

Creo que el escaneo es más parecido a un c y probablemente más eficiente y me gustaría seguir también – Jose

+1

@jocapco, si "c-like" es importante, ¿por qué Ruby? –

+0

no es importante, es simplemente bueno :) ..ruby porque lo que estoy haciendo requiere que el usuario sepa muy poco y haga mucho ... usar el lenguaje de script como ruby ​​sería preferible entonces. Solo sigo haciendo cosas a pequeña escala. – Jose

Cuestiones relacionadas