2009-02-27 5 views
1

utilisant des extensions fournies par .net, on peut trouver des groupes de parenthèses en utilisant quelque chose comme ceci:Comment trouver une virgule qui n'est pas entre parenthèses dans une expression régulière .net?

^(\w+)\(((?>[^()]+|\((?<D>)|\)(?<-D>))*(?(D)(?!)))\)(.*)$ 

Cela correspondra à la suivante:

Func(innerfunction(arg)).DoSomething() 

avec les groupes suivants:

  • Groupe 1: Func
  • Groupe 2: fonction interne (arg)
  • Groupe 3: .DoSomething()

Ma question est, comment puis-je correspondre à des virgules, en prenant en compte si elles sont ou non à l'intérieur d'un groupe entre parenthèses? Par exemple, une expression rationnelle pour évaluer:

Func(innerFunction(arg1, arg2), arg3).DoSomething() 

céderais:

  • Groupe 1: Func
  • Groupe 2: innerFunction (arg1, arg2)
  • Groupe 3: arg3
  • Groupe 4: .DoSomething()

Merci.

Répondre

0

Je pense que je l'ai trouvé. Quelqu'un at-il un contre-exemple:

^([^()]*?|.*\((?>[^()]+|\((?<D>)|\)(?<-D>))*(?(D)(?!))\).*?),(.*)$ 

Cela correspondra cette expression:

func1(arg2, func3(arg3, arg4)), func2(arg5, arg6).property 

comme:

  • Groupe1: func1 (arg2, fonc3 (arg3, arg4))
  • Groupe2: func2 (arg5, arg6) .property

Cette solution ne recherche qu'une virgule, mais elle prend en compte une profondeur de parenthèse arbitraire.

MISE À JOUR: Gumbo a fourni un contre-exemple:

func1((arg1), arg2), func2(arg3).property 

get subdivisée en types:

  • Groupe1: func1 ((arg1)
  • Group2: arg2), func2 (arg3).propriété

CEPENDANT: En tournant la première "toute correspondance" en non-gourmand, on peut le résoudre:

^([^()]*?|.*?\((?>[^()]+|\((?<D>)|\)(?<-D>))*(?(D)(?!))\).*?)\s*,\s*(.+)$ 

Toute autre contre-exemple?

+0

Voici un exemple de ce qui ne correspond pas: "func1 ((arg1), arg2), func2 (arg3) .property" get est divisé en "func1 ((arg1)" et "arg2), func2 (arg3) .property "(accodring à ). – Gumbo

+0

Et maintenant? ;-) –

+1

Qu'en est-il de quelque chose comme ceci: "func1 (") ", arg1), func2(). Property"? – Gumbo

0

Bien que ce ne soit pas impossible, je déconseille d'utiliser des expressions régulières pour cela.

Le problème est que les expressions ont tendance à être complètement gourmandes ou complètement non gourmandes. Par exemple, prendre l'entrée suivante:

(a,) b, (c, (d), e,)

Une expression avide correspondrait autant que possible. Il verra tout comme à l'intérieur des parenthèses, et donc retourner rien.

Une expression non cohérente correspondrait correctement à la virgule b, mais elle correspondrait également à la virgule car elle verrait (c,(d,) comme un groupe complet. Maintenant, il semble que vous compreniez déjà ces problèmes, et que le moteur d'expressions régulières .Net a une fonctionnalité qui vous permettra de dépasser cela dans une certaine mesure. Mais l'expression du résultat sera laide, indéfinissable, pas très portable, et facile à se tromper. Sauf si vous savez vraiment ce que vous faites, il est probablement préférable de chercher une autre solution.

0

Si vous ne souhaitez pas limiter la profondeur d'imbrication, cela est impossible avec les expressions régulières uniquement.

Je vous recommande donc de construire un analyseur qui décompose les niveaux d'imbrication. Lire le caractère d'entrée par caractère. Quand c'est un "(" augmenter le niveau, quand c'est un ")" diminuer le niveau, quand c'est un "," séparé.

+0

) Merci pour le conseil. –

+0

+1 Regex ne peut pas gérer l'imbrication de la profondeur arbitraire, un autre type d'analyseur est nécessaire – bobince

+0

Je continue à affirmer que la solution présentée résout le problème et que l'imbrication à la profondeur arbitraire est résolue , et stratégie de comptage :) Tout contre-exemple, s'il vous plaît? –

Questions connexes