2015-12-05 3 views
5

Ich bin auf der Suche nach einem regulären Ausdruck, der eine Zeichenfolge geteilt wird, wie folgt:Regex für die Spaltung bei jedem Charakter, sondern halte Zahlen zusammen

String input = "x^(24-3x)"; 
String[] signs = input.split("regex here"); 
for (int i = 0; i < signs.length; i++) { System.out.println(sings[i]); } 

mit dem Ausgang ergibt:

"x", "^", "(", "24", "-", "3", "x", ")" 

Die Zeichenfolge ist bei jedem Zeichen aufgeteilt. Wenn jedoch Ziffern nebeneinander stehen, sollten sie in einer Zeichenfolge gruppiert bleiben.

Antwort

4

können Sie diese Lookarounds basierte regex verwenden:

String[] signs = input.split("(?<!^)(?=\\D)|(?<=\\D)"); 

RegEx Demo

RegEx Breakup

(?<!^)(?=\\D) # assert if next char is non-digit and we're not at start 
|    # regex alternation 
(?<=\\D)  # assert if previous character is a non-digit 
+1

Vollkommen in Ordnung, auch mit Erklärung. Vielen Dank. – Zi1mann

+1

sehr schlau, sehr knifflig –

+0

Können Sie teilen, warum die Prüfung, dass Sie nicht am Start sind, benötigt wird? Ich habe es mit drei Testfällen getestet -> "", "123", "aa123" und in allen drei Fällen habe ich das gleiche Ergebnis erhalten, egal ob ich das einbeziehe oder nicht. Regex101 zeigt einen Unterschied für PCRE, aber für Java kann ich keinen Unterschied in den Ergebnissen sehen. –

0

Sie auch Muster und Matcher in Token verwenden können, teilen, die vielmehr lesbar

String regex="\\d+|[a-z]+|[\\-()\\^]"; 
String str="x^(24-3x)"; 

wenn funktioniert auch einfach mit str = "xxx^(24-3xyz)";

alle Token zu bekommen, ist es ein wenig schwierig:

Ich benutze diese:

mit freundlicher Genehmigung von: Create array of regex matches

for (MatchResult match : allMatches(Pattern.compile(regex), str)) { 
    System.out.println(match.group() + " at " + match.start()); 
} 

public static Iterable<MatchResult> allMatches(
     final Pattern p, final CharSequence input) { 
    return new Iterable<MatchResult>() { 
    public Iterator<MatchResult> iterator() { 
     return new Iterator<MatchResult>() { 
     // Use a matcher internally. 
     final Matcher matcher = p.matcher(input); 
     // Keep a match around that supports any interleaving of hasNext/next calls. 
     MatchResult pending; 

     public boolean hasNext() { 
      // Lazily fill pending, and avoid calling find() multiple times if the 
      // clients call hasNext() repeatedly before sampling via next(). 
      if (pending == null && matcher.find()) { 
      pending = matcher.toMatchResult(); 
      } 
      return pending != null; 
     } 

     public MatchResult next() { 
      // Fill pending if necessary (as when clients call next() without 
      // checking hasNext()), throw if not possible. 
      if (!hasNext()) { throw new NoSuchElementException(); } 
      // Consume pending so next call to hasNext() does a find(). 
      MatchResult next = pending; 
      pending = null; 
      return next; 
     } 

     /** Required to satisfy the interface, but unsupported. */ 
     public void remove() { throw new UnsupportedOperationException(); } 
     }; 
    } 
    }; 
} 
Verwandte Themen