def replaceAllFullMatches(text: String, replacement: String) : String = { var newText = text var nextMatch: Option[(Full, Option[Group])] = None var startIndex = 0
do { val matcher = regexCompiled.matcher(newText) nextMatch = findNextMatch(matcher, startIndex) if (nextMatch != None) { newText = replaceText(newText, nextMatch.get._1.startPositionMatching, nextMatch.get._1.matching.length, replacement) startIndex = nextMatch.get._1.startPositionMatching + replacement.length } } while (nextMatch != None) newText }
def replaceAllGroupMatches(text: String, replacement: String) : String = { var newText = text var nextMatch: Option[(Full, Option[Group])] = None var startIndex = 0
do { val matcher = regexCompiled.matcher(newText) nextMatch = findNextMatch(matcher, startIndex) if (nextMatch != None && nextMatch.get._2 != None) { newText = replaceText(newText, nextMatch.get._2.get.startPositionMatching, nextMatch.get._2.get.matching.length, replacement) startIndex = nextMatch.get._2.get.startPositionMatching + replacement.length } } while (nextMatch != None) newText }
private def compile() : Pattern = { var result = Pattern.compile("")
try { result = Pattern.compile(regex) } catch { case ex: PatternSyntaxException => throw new RegexSyntaxException(ex.getMessage) } result }
private def replaceText(text: String, startPosition: Int, length: Int, replacement: String) : String = { val before = text.substring(0, startPosition) val after = text.substring(startPosition + length) before + replacement + after }
private def fillResult(matcher: Matcher) : MatchResult = { var fulls = Seq[Full]() var groups = Seq[Group]()
val regexHasGroup = if (matcher.groupCount() == 0) false else true
def findNextAndFillResultRec(matcher: Matcher, matchN: Int) : MatchResult = { val findNext = matcher.find() if (matchN == 1 && ! findNext) { MatchResult(isMatching = false, regexHasGroup, isGroupMatching = false, Seq[Group](), Seq[Full]()) } else if (findNext) { // calculate result val fullStartPosition = matcher.start() val fullMatch = matcher.group()
fulls = fulls:+Full(fullMatch, fullStartPosition)
var groupStartPosition = 0
breakable { for (i <- 1 to matcher.groupCount()) { groupStartPosition = matcher.start(i) if (groupStartPosition != -1) { groups = groups:+Group(matcher.group(i), groupStartPosition, i) break } } }
findNextAndFillResultRec(matcher, matchN + 1) } // NOT (matcher.find()) else { val isMatching = if (fulls.size > 0) true else false val isGroupMatching = if (groups.size > 0) true else false MatchResult(isMatching, regexHasGroup, isGroupMatching, groups, fulls) } }
findNextAndFillResultRec(matcher, 1) }
def findNextMatch(matcher: Matcher, startIndex: Int) : Option[(Full, Option[Group])] = { var resultFull = Full("", 0) var resultGroup: Option[Group] = None
val findNext = matcher.find(startIndex) if (! findNext) { None } else { // calculate result val fullStartPosition = matcher.start() val fullMatch = matcher.group()
resultFull = Full(fullMatch, fullStartPosition)
var groupStartPosition = 0
breakable { for (i <- 1 to matcher.groupCount()) { groupStartPosition = matcher.start(i) if (groupStartPosition != -1) { resultGroup = Some(Group(matcher.group(i), groupStartPosition, i)) break } } }
Dieses kleine Projekt soll die Auswertung von regulären Ausdrücken standardisieren, um bei der Nutzung von diesen Ausdrücken sich nur noch auf den Ausdruck selber und das Auswertungsergebnis zu konzentrieren.
Zusätzlich soll diese Auswertung bei der Modifikation von Strings genutzt werden.
Mit der Klasse 'String' bringt Java unter anderem die Methode 'String replaceAll(String regex, String replacement)' mit.
Das Treffen des regulären Ausdrucks bezieht sich dabei immer auf die Vollmatches und nicht auf die eventuell vorhandenen Gruppenmatches. Beispiel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
package de.rehnfalk.stringmodificatorwithregex
object Application { def main(args: Array[String]) { val text = " sdiuh ivuhv ahGTG787auhv viu fvua MRE_66543 fviv v v T_498 6656ui26h5h56 69hg8 b zb7sg7 g"; val result1 = text.replaceAll("[A-Z]+_[0-9]+", "STD_123"); val result2 = text.replaceAll("([A-Z])+_[0-9]+", "XXX"); System.out.println(result1); System.out.println(result2);
// print out: // sdiuh ivuhv ahGTG787auhv viu fvua STD_123 fviv v v STD_123 6656ui26h5h56 69hg8 b zb7sg7 g // sdiuh ivuhv ahGTG787auhv viu fvua XXX fviv v v XXX 6656ui26h5h56 69hg8 b zb7sg7 g } }
Also wäre ein Ziel des Projekts an dieser Stelle eine Unterscheidung einzuführen.
if (obj instanceof List<?>) { @SuppressWarnings("unchecked") List<Object> newList = new Vector<Object>((List)obj); reflectionToStringBuilder = new ReflectionToStringBuilder(newList, new MultilineRecursiveToStringStyle()); } else { reflectionToStringBuilder = new ReflectionToStringBuilder(obj, new MultilineRecursiveToStringStyle()); } return reflectionToStringBuilder.toString();
Anmerkung: Die Nutzung des MultilineStyles ist ab der Version 3.5 möglich, da diese Klasse in den vorherigen Versionen Package-Private ist.
wenn man in einem regulären Ausdruck Gruppen verwendet, ist die Auswertung des Treffens eines Textes auf den Ausdruck abhängig von der Gestaltung des Ausdrucks.
So wird bei dem Ausdruck '([A-Z]+_[0-9]+)|([0-9]+)' mit dem Text 'ztr ZU U _ SINN_41 876 u TREE' nach dem Aufrufen der Methode 'find()' in der Methode 'group(1)' der String 'SINN_41' zurückgeliefert.
Nun meine Frage, ist die Abhängigkeit der Auswertung (Angabe der 1 für die erste Gruppe oder 2 für die zweite) gewollt? Der Nachteil ist nämlich, dass bei einer Änderung des regulären Ausdrucks die Abfrage auch geändert werden muss.
ich bin bin bisher ganz zufrieden mit der toString-Umwandlung von unbekannten Objekten mittels Apache-commons-lang3 und dem ReflectionToStringBuilder.
Jetzt bin ich aber darauf gestoszen, dass mir diese Bibliothek für ein Objekt mit einer List das Ergebnis 'ArrayList[size=2]' liefert. Die dafür genutzte Einstellung sieht wie folgt aus:
in der nächsten Zeit ist ein Treff der Dresden Scala Gruppe geplant, bei dem es einen Vortrag geben wird. Diese Treffs sollen weiterhin bestehen bleiben.
Zusätzlich zu den Treffs habe ich gedacht, einen 'Dresden Scala Stammtisch' ins Leben zu rufen. Dieser soll aber nicht bei AvantgardeLabs stattfinden, sondern auf 'neutralem' Boden zum Beispiel in einer Kneipe.
Zum Unterschied zu den Vortragstreffs soll hier der Fokus auf Kommunikation, Sozializing und auch Scalageschwätz liegen. Der Vorteil hier wäre dass Anfänger hier besser unterstützt werden.
Als Termin schlage ich den Montag, den 24. Oktober 2016 um 20:00 Uhr und als Treffpunkt provisorisch 'Cafe Müllers' auf der Bergstrasse vor.
Wenn ich das richtig verstanden habe, sollte man alle gefangenen Exceptions auf Verschachtelung prüfen und wenn diese besteht, bei der zu erstellenden eigenen Exception den originalen Nachrichtentext einbauen und die Ursprüngliche Exception nicht im Konstruktor verwenden.
Exceptions haben bekannterweise vier Konstruktoren - den Standardkonstruktor, einen Konstruktor mit der Nachricht, einen Konstruktor mit der Ursache und einen mit beiden als Parameter.
Gibt es eine beste Praxis für die Nutzung der Konstruktoren, eigentlich der letzten drei, so dass die Verschachtelung der Exceptions nicht zu einem unauflösbaren Knäul führt, der 'catch'-Bereich möglichst einfach bleibt und der Stacktrace gut leserlich wird (wahrscheinlich kann man an dem Stacktrace nicht so viel ändern) (insbesondere bei mehrmals ineinander geschachtelten Exceptions) ?
Meine zweite Frage: Wie sinnvoll ist der Entwurf einer eigenen Exceptionshierarchie (bei Mehrschichtenarchitekturen oder bei Applikationen mit vielen Komponenten), um die oben aufgeführten Ziele zu erreichen?
Derzeit bin ich noch am recherchieren, ob code-prettify eingesetzt werden kann.
Ich habe dazu im Hilfeforum einen Beitrag geschrieben.
Falls diese Funktionalität nur über Plugins realisiert werden kann, müsste man eines selber schreiben (in der kostenlosen Version des Forums ist EIN Plugin möglich) und es würde zudem noch eine Weile dauern bis das Forum starten kann.