2009-07-13 20 views
2

Dies ist nicht so einfach wie es scheint. Die meisten von euch denken wahrscheinlich an die Regex /([A-Z])/_$1/, wie ich sie überall im Internet gefunden habe, aber meine spezielle Situation ist etwas komplizierter. Meine Source-Zeichenfolge enthält mehr Inhalt, den ich nicht vor einem Teil konvertiert haben möchte, dass ich tun.Pascal-Setter in einen Unterstrich-getrennten Variablennamen konvertieren

Betrachten sie einen regelmäßigen Setzer:

public function setUserId() 

Natürlich ist diese Methode einen Parameter fehlt. Vielleicht habe ich viele dieser Methoden. Ich mag, dass die Linie konvertieren in

public function setUserId($user_id) 

das ist eine ziemlich einfache Sache zu prüfen, aber nicht so einfach, wie ich es tiefer nachzudenken. Es ist ähnlich wie Andreas_D in this thread, aber mit der zusätzlichen Herausforderung zu versuchen, den Variablennamen iterativ zu ändern ...

Es wird wahrscheinlich etwas offensichtlich mit regulären Ausdrücken, aber ich bin immer noch ziemlich neu mit ihnen. Wie auch immer, ich kann nirgendwo eine vernünftige Lösung für dieses Problem finden.

Edit: natürlich, ich weiß, dass es keine Hauptstädte in "öffentlichen Funktionen" gibt, die es sicher machen. Aber diese Suche & Substitution wird gegen Blöcke von Code ausgeführt, und ich möchte sicherstellen, dass die Zeichenfolge, die ich geändert mit "öffentliche Funktion" beginnt.

Antwort

2

Zuerst nach Funktionsdefinitionen suchen und dann bei jeder Übereinstimmung einen Parameter basierend auf dem Funktionsnamen einfügen.

/\b(function\s+set([A-Z]\w*))\b\s*\(\)/g 

Dieses Muster geben entsprechen, die Sie mit dem function -keyword und den Funktionsnamen in der Gruppe 1, und der Kamel-verrohrten Teil des Funktionsnamen in Gruppe 2.

/([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))/g 

Dieses Muster wird Finde den letzten Buchstaben vor einer Groß-/Kleinschreibung, die einen Kamelfall darstellt.

Sie nicht angeben, welche Sprache Sie verwenden werden, so ist hier eine Demonstration mit Python:

import re 

pattern1 = re.compile(r'\b(function\s+set([A-Z]\w*))\b\s*\(\s*\)') 
pattern2 = re.compile(r'([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))') 

def fix_setters(code): 
    def replacer(match): 
     var_name = pattern2.sub(r'\1_', match.group(2)).lower() 
     return "%s($%s)" % (match.group(1), var_name) 
    return pattern1.sub(replacer, code) 

Die letzte Zeile („return pattern1.sub(replacer, code)“), verwendet einen Rückruf, den Text zu generieren werden ersetzt . In den meisten Sprachen sollte es ähnliche Funktionen geben.

Python (vor Version 3.0) verwendet den Modulo-Operator ("%") zum Formatieren, ähnlich wie sprintf in z. die Sprache C.

Beispiel:

>>> s = """\ 
... public function setUserName() { 
... blaha 
... } 
... """ 
>>> print s 
public function setUserName() { 
    blaha 
} 

>>> print fix_setters(s) 
public function setUserName($user_name) { 
    blaha 
} 

>>> 

Weitere Informationen: .NET - How can you split a “caps” delimited string into an array?

+0

FANTASTISCHEN MizardX. Dies ist genau das, was ich brauchte und es funktioniert super. Ich kenne Python noch nicht (habe immer noch vor zu lernen ...), aber es ist eine sehr intuitive Sprache, leicht zu lesen. Sehr gute Wahl für einen Testfall. – JMTyler