2010-06-22 5 views
1

Je tente de diviser l'instruction ORDER BY d'une requête SQL en tableau. inclinaison première est:Fractionner une instruction ORDER BY en un tableau

order_by.split(',') 

mais cela ne fonctionne pas pour l'ordre par des déclarations comme les suivantes:

SUBSTRING('test',1,3) ASC, SUBSTRING('test2', 2,2) DESC 

La sortie souhaitée pour la déclaration ci-dessus serait:

["SUBSTRING('test',1,3) ASC", "SUBSTRING('test2', 2,2) DESC"] 

Je suis assez certain que cela fonctionnerait si je pouvais faire correspondre n'importe quelle virgule qui n'est pas incluse dans la parethesis, mais je ne peux pas trouver un moyen de le faire dans ruby ​​regex parce que lookbehind n'est pas supporté.

Répondre

0

Bien que je soupçonne qu'il existe probablement encore une façon de le faire avec regex, vous pouvez le faire avec une simple analyse de chaîne.

Trouvez toutes les virgules dans la chaîne, puis allez en avant ou en arrière à partir de ce point (peu importe si les parenthèses sont équilibrées correctement), en ajoutant une pour une accolade ouverte et en soustrayant une pour une accolade fermée. Si vous n'avez pas 0 à la fin, vous êtes à l'intérieur d'une accolade, donc ce n'est pas une virgule que vous voulez.

Division sur toutes les autres virgules.

EDIT

Bien que le commentaire au sujet de cette méthode ne dans le cas des parenthèses enfermées dans des virgules est valide, il peut être le cas que vous avez affaire à des requêtes assez simples ne vous inquiétez pas à ce sujet. Si tel est le cas, cela devrait fonctionner:

def in_brackets(str,pos) 
    cnt = 0 
    str[pos,str.length].each_char do |c| 
    if c == '(' 
     cnt += 1 
    elsif c == ')' 
     cnt -= 1 
    end 
    end 

    return cnt != 0 
end 

def split_on_some_commas(str) 
    offset = -1 
    split_pts = [] 

    while (offset = str.index(",",offset+1)) 
    if !in_brackets(str,offset) 
     split_pts << offset 
    end 
    end 

    split_pts << str.length 

    pos = 0 

    ret = [] 
    split_pts.each do |pt| 
    ret << str[pos..(pt-1)].strip 
    pos = pt+1 
    end 

    return ret 
end 

puts split_on_some_commas("SUBSTRING('test',1,3) ASC, SUBSTRING('test2', 2,2) DESC, SUBSTRING('test2', 2,2) DESC").inspect 
+0

Eh bien cela fait le travail, j'espérais quelque chose d'un peu plus concis. Mais je crois que c'est la meilleure façon. Merci! –

1

La méthode la plus simple serait de faire un preg_replace_callback pour remplacer les parenthèses avec un porte-place, puis exploser les données, puis boucle à travers et de mettre la parenthèse en arrière.

0

En général, vous ne pouvez pas utiliser d'expressions régulières pour analyser un langage non régulier. Essayez d'utiliser Rockit pour créer une véritable grammaire et un analyseur pour le sous-ensemble de SQL dont vous avez besoin.

Questions connexes