2015-01-20 12 views
8

Wie könnten Sie in einer ungeraden Zahlenlänge den mittleren Buchstaben abgleichen?Wie das mittlere Zeichen in einer Zeichenfolge mit Regex übereinstimmen?

Ist dies mit PCRE möglich, plain Perl oder Java Regex Aromen?

Mit .NET Regex könnten Sie balancing groups verwenden, um es leicht zu lösen (das könnte ein gutes Beispiel sein). Mit dem normalen Perl-Regex meine ich, dass ich keine Code-Konstrukte wie (??{ ... }) verwende, mit denen man irgendeinen Code ausführen und natürlich alles machen könnte.

Die Zeichenfolge könnte eine beliebige ungerade Nummernlänge haben.

Zum Beispiel in der Zeichenfolge 12345 möchten Sie die 3, das Zeichen in der Mitte der Zeichenfolge.

Dies ist eine Frage über die Möglichkeiten der modernen Regex-Aromen und nicht über den besten Algorithmus, um das auf andere Weise zu tun.

+6

Perl: Ja. Verwenden von Rekursion oder '/^(. *) (.) (?? {'.' X Länge ($ 1)}) \ z/s' – ikegami

+0

Ist das nicht kontextsensitiv? – Oli

+0

@ikegami, ich denke, ich hätte Perl nicht oder zumindest nicht mit Perl-Code sagen sollen. In diesem Fall können Sie auch eine grundlegende String-Funktion verwenden. – Qtax

Antwort

7

Mit PCRE und Perl (und wahrscheinlich Java) Sie nutzen könnten :

^(?:.(?=.*?(?(1)(?=.\1$))(.\1?$)))*(.) 

, die das mittlere Zeichen von Strings mit ungerader Länge in der zweiten Erfassungsgruppe erfassen würde.

Explained:

^ # beginning of the string 
(?: # loop 
    . # match a single character 
    (?= 
    # non-greedy lookahead to towards the end of string 
    .*? 
    # if we already have captured the end of the string (skip the first iteration) 
    (?(1) 
     # make sure we do not go past the correct position 
     (?= .\1$) 
    ) 
    # capture the end of the string +1 character, adding to \1 every iteration 
    (.\1?$) 
) 
)* # repeat 
# the middle character follows, capture it 
(.) 
+2

Ich habe folgendes gefunden: '^ (?:. (? =. * ((? (1). \ 1 |.)) $)) * \ K..das ist nicht sehr verschieden. –

+2

oder mit dem richtigen Quantifizierer: '^ (?:. (? =. + ((? (1). \ 1 |.)) $)) * \ K.' –

+2

@CasimiretHippolyte, nette Lösung, +1! Du solltest es posten. – Qtax

1

Hmm, vielleicht kann jemand mit einer reinen Regex Lösung kommen, aber wenn du nicht immer dynamisch die Regex wie folgt aufbauen könnte:

public static void main(String[] args) throws Exception { 
    String s = "12345"; 
    String regex = String.format(".{%d}3.{%d}", s.length()/2, s.length()/2); 
    Pattern p = Pattern.compile(regex); 
    System.out.println(p.matcher(s).matches()); 
}