toUpperString "verschluckt" Teil von String?

JayP

Grünschnabel
Hallo zusammen,

bei meinem ersten Post erstmal ein großes Lob an tutorials.de. Hat mir schon eine Menge geholfen :)

Jetzt aber mal zu meinem Problem:
Ich erstelle momentan ein Programm, das unteranderem bestimmte Textpassagen aus PDF's(mittels iText) auslesen soll. Ich lasse mir dabei den gesamten Text des PDF's in einem String wiedergeben und werte diesen mit verschiedenen "Parse-Methoden" aus.

Dabei kann der User die Suchen selbst mittels einer .xml einstellen, da sich die Formatierung der PDF's häufig ändert und statische Suchen festcodiert im Quelltext somit nicht optimal geeignet wären.
Das alles klappt eigentlich auch wunderbar, nur bin ich jetzt bei einem Fallbeispiel auf einen "Fehler" gestoßen, den ich mir beim besten Willen nicht erklären kann:

Und zwar versuche ich aus dem String, mittels zweier Suchwörter den Text dazwischen auszugeben:
Bsp. Such1= Hallo
Such2= gehts?
Text= Hallo wie gehts? ---> Rückgabe sollte demnach "wie" sein.

Die Methode dazu(etwas gekürzt):
textContent= der String aus der PDF
node = die node aus der XML (in der verkürzten Version nicht verwendet)
Code:
private String parse3(String textContent, Node node) {
		String such1;
		String such2;
		String content;
		try{
			such1= //Suchwort1 aus XML .toUpperCase();
			such2= //Suchwort2 aus XML .toUpperCase();
			if (textContent.toUpperCase().contains(such1)){
				content= textContent.substring(textContent.toUpperCase().indexOf(such1)+such1.length());
				if (content.toUpperCase().contains(such2)){
					content= content.substring(0,content.toUpperCase().indexOf(such2));
					if (content.endsWith("\\n")) {
						content=content.substring(0,content.length()-2);
					}
				}
				else {
					content = null;
					logger.info("Kein Inhalt gefunden.");
				}
			}
			else {
				content = null;
				logger.info("Kein Inhalt gefunden.");
			}
		} catch(Exception e){
			content = null;
			logger.info("Kein Inhalt gefunden.");
			logger.error(e.getMessage());
		}
		if (inhalt==null){
			inhalt=content;
		}
		else{
			inhalt=inhalt+"\n"+content;
		}
		return inhalt;
	}
Wie man sieht lasse ich beim Vergleich die Suchwörter UND den gesamten zu durchsuchenden String mittels toUpperCase() vergleichen, falls der Benutzter z.B. in der XML ein Wort kleingeschrieben einträgt, es tatsächlich aber Groß-Kleinschreibung verwendet etc.

An dieser Stelle scheint auch der Fehler aufzutreten bei folgendem String:
"A-#110;-#108;age zur Kalkulation 1020039 001" (Erstmal ist schon merkwürdig das in der PDF Anlage mit komischen Zeichen geschrieben ist ;) )

Wenn ich nun an die parse-Methode als Suchwort1: "age zur Kalkulation" und als Suchwort2="001" übergebe, sollte rein logisch?! ja "1020039" ausgegeben werden.
Als Rückgabe erhalte ich aber 20039.
Wenn ich Suchwort1 nun mit "age zur Kalkulati" belege kommt als Ergebnis "1020039" heraus.
Mittels logger habe ich auch schon überprüft ob der String textContent und such1, such2 richtig mit .toUpperCase() umgesetzt werden, was laut Consolen-Ausgabe dann richtig funktioniert.

Wenn ich nun das .toUpperCase weglasse, und die Suchwörter richtig "formatiere"
funktioniert auch alles wunderbar, jedoch kann ich darauf nicht verzichten.

Darum dachte ich mir es könnte vll. an einer falschen Locale bei .toUpperCase() handeln aber selbst wenn ich diese richtig setzte funktioniert es nicht.

Dsa merkwürdig ist: Das passiert bis jetzt NUR bei genau diesen Suchwörtern sonst funktioniert alles "wie es sollte" :eek:

Jemand eine Idee woran es liegen kann?
Hoffe ich habe das Problem ein wenig eingegrenzt, falls aber noch fragen bestehen immer gerne :)
(Die PDF's aus der ich den textContent auslese, kann/darf ich leider nicht zur Verfügung stellen :()

Beste Grüße und schonmal vielen Dank
JayP
 
In manchen PDF's steht es richtig drinne:
Anlage zur Kalkulation
in anderen:
A-#110;-#108;age zur Kalkulation
unabhängig davon ob ich es mit Adobe öffne oder via Java iText einlese.
Denke, dass da einfach was bei der PDF-Erstellung falsch läuft, mit der ich aber nichts zutuen habe. :eek:

Denke aber, dass mein eigentliches Problem unabhängig davon ist,
da ich ja einfach als Suchwort "age zur Kalkulation" übergebe, was bei beiden ja enthalten ist.

Das was ich bis jetzt auch "herausgefunden" habe, weißt auch eindeutig darauf hin, dass irgendwas mit dem toUpperString() falsch läuft.
Wie gesagt, wenn ich alles(Suchwörter und Suchstring) mit toUpperCase überschreibe kriege ich auch den String und die Suchwörter im Logger richtig komplett groß geschrieben(Kalkulation auch MIT "ON") sobald es dann mit dem substring aber "bearbeitet" werden bei der Rückgabe die ersten Zeichen abgehackt.

Test1:
Suchstring:A-#110;-#108;age zur Kalkulation 1020039 001
Such1: age zur Kalkulation
Such2: 001
Rückgabe: 20039

Test2: (Kalkulati statt Kalkulation)
Suchstring:A-#110;-#108;age zur Kalkulation 1020039 001
Such1: age zur Kalkulati
Such2: 001
Rückgabe: 1020039

Test3:
Suchstring:Anlage zur Kalkulation 1020039 001 //andere PDF als erste
Such1: age zur Kalkulation
Such2: 001
Rückgabe: 20039

Test4: (Kalkulati statt Kalkulation)
Suchstring:Anlage zur Kalkulation 1020039 001 //andere PDF als erste
Such1: age zur Kalkulati
Such2: 001
Rückgabe: 1020039

Für mich unerklärbar, da die Substring Methode bei allen anderen Fallbeispielen funktioniert...
 
Zuletzt bearbeitet:
Ich kann mir vorstellen, dass das Problem für andere schwer zu reproduzieren ist, da ich die PDF's(mit Kundendaten :eek:) nicht zur Verfügung stellen kann. Hoffe nur, dass vielleicht trotzdem jemand einen blendenden Einfall hat :)
 
Hi.

Du solltest diese toUpperCase Aufrufe am besten vermeiden. Nicht für jedes Zeichen gibt es überhaupt einen Großbuchstaben, kann z.B. sein, das ein ß zu SS umgesetzt wird, so dass also dein Index aus dem Großbuchstaben-String nicht mit dem Index im Originalstring übereinstimmt.

Außerdem ist es nicht gerade performant den ganzen Text in Großbuchstaben zu konvertieren, dann einen Substring auszuschneiden, nochmal toUpperCase .... :eek:

Kannst du denn von Java 1.5 (Pattern.quote gibt's erst seit 1.5) ausgehen? Dann verwende einfach reguläre Ausdrücke:
Java:
Pattern p = Pattern.compile(Pattern.quote(such1) + "(.*?)" + Pattern.quote(such2),
  Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.UNICODE_CASE);
Matcher m = p.matcher(content);
if (m.find()) return m.group(1);
Gruß
 
Zuletzt bearbeitet:
Das mit dem Pattern werde ich mir aufjedenfall mal anschauen!
Dass das mit dem toUpperCase() auch nicht die schönste Lösung ist weiß ich, aber dachte es wäre eine einfache Lösung :)

Bezüglich des ß zu SS stimmt soweit ich weiß nicht ganz. Die jeweilige Locale der Sprache die toUpperCase verwendet gibt soweit ich weiß doch an, in welchen "Großbuchstaben" der Buchstabe transferiert wird. Wenn die Locale Deutsch ist dürfte ß in klein ebenfalls ß in groß sein.
Kann natürlich aber auch sein das ich mich irre. :eek:
Außerdem wäre es dann trotzdem merkwürdig, dass die Methode eig bis jetzt überall geklappt außer bei diesem Fall wo ein "on" nicht in "ON" umgewandelt werden kann?

Nichtsdestotrotz falls das mit Pattern klappt bin ich auch sehr zufrieden, da es eindeutig schonmal wesentlich "schöner" codiert ausschaut :)
 
Zuletzt bearbeitet:
Also es funktioniert auf jedenfall mit dem Pattern darum Vielen Dank für den Tipp******!
Mir erklärt sich so zwar immer noch nicht genau woran es jetzt lag aber das Problem ist ja somit behoben.
Danke!
 
Bezüglich des ß zu SS stimmt soweit ich weiß nicht ganz. Die jeweilige Locale der Sprache die toUpperCase verwendet gibt soweit ich weiß doch an, in welchen "Großbuchstaben" der Buchstabe transferiert wird.
Eben. Und welche Locale verwendest du?
Note: This method is locale sensitive, and may produce unexpected results if used for strings that are intended to be interpreted locale independently. Examples are programming language identifiers, protocol keys, and HTML tags. For instance, "title".toUpperCase() in a Turkish locale returns "T?TLE", where '?' is the LATIN CAPITAL LETTER I WITH DOT ABOVE character. To obtain correct results for locale insensitive strings, use toUpperCase(Locale.ENGLISH).
Wenn die Locale Deutsch ist dürfte ß in klein ebenfalls ß in groß sein.
Kann natürlich aber auch sein das ich mich irre. :eek:
Kommt drauf an, bzw. probiers doch mal aus. Ein versales ß gibt es noch nicht so lange (Unicode 5.1 April 2008) bzw. ist noch nicht so verbreitet ß uppercase => ?
Außerdem wäre es dann trotzdem merkwürdig, dass die Methode eig bis jetzt überall geklappt außer bei diesem Fall wo ein "on" nicht in "ON" umgewandelt werden kann?
Es liegt nicht an "on". Wie kommst du denn darauf? Du hast doch nur künstlich den Index korrigiert indem du 2 Zeichen vom Suchstring weggelassen hast. Schau doch mal ob textContent.length() == textContent.toUpperCase().length() ist. Sehr wahrscheinlich nicht. Gib doch einfach mal die Bytes von "Anlage" aus. Evtl. handelt es sich auch um ungültige Unicode Codepunkte.

Gruß
 
Ich würde mal sagen Volltreffer deinerseits!
Jetzt wo du es sagst, ist das Ganze ziemlich einleuchtend.
Hatte da wohl vorher eine kleine Denkblockade. :eek:
 
Zurück