Discussion:
String auf Großbuchstabe validieren
(zu alt für eine Antwort)
m***@gmx.de
2007-09-27 11:12:26 UTC
Permalink
Hallo,

ich möchte überprüfen, ob ein String mindestens einen Großbuchstaben
enthält. Wie kann ich das tun? Reguläre Ausdrücke?

Danke im Voraus,
David
Andreas Eberhöfer
2007-09-27 11:24:27 UTC
Permalink
Hallo David,
Post by m***@gmx.de
Hallo,
ich möchte überprüfen, ob ein String mindestens einen Großbuchstaben
enthält. Wie kann ich das tun? Reguläre Ausdrücke?
Am einfachsten machst du es so:

public static void hatGrossbuchstaben(String s)
{
for(int i=0;i<s.length();i++)
{
char c = s.charAt(i);
if(Charcater.isUpperCase(c))
return true;
}
}

mfg
Andreas
d***@googlemail.com
2007-09-27 11:28:39 UTC
Permalink
Oder lass die Libraray die Schleifen-Arbeit machen:

boolean isLowerCaseLetterOnly(String s) {
return s.equals(s.toLower);
}

oder halt:

boolean hasUpperCaseLettersString s) {
return ! s.equals(s.toLower);
}
Post by Andreas Eberhöfer
Hallo David,
Post by m***@gmx.de
ich möchte überprüfen, ob ein String mindestens einen Großbuchstaben
enthält. Wie kann ich das tun? Reguläre Ausdrücke?
public static void hatGrossbuchstaben(String s)
{
for(int i=0;i<s.length();i++)
{
char c = s.charAt(i);
if(Charcater.isUpperCase(c))
return true;
}
}
mfg
Andreas
m***@gmx.de
2007-09-27 11:42:07 UTC
Permalink
super, danke
Ralf Ullrich
2007-09-27 13:57:18 UTC
Permalink
Post by d***@googlemail.com
boolean isLowerCaseLetterOnly(String s) {
return s.equals(s.toLower);
}
boolean hasUpperCaseLettersString s) {
return ! s.equals(s.toLower);
}
Diese beiden Implementationen bitte möglichst schnell wieder vergessen
bzw. als Beispiel, wie man es NICHT machen sollte, einrahmen.

Grund: Diese Methoden tun nicht was der Autor vielleicht dachte, dass sie
tun würden, denn sie basieren auf der falschen Annahme, dass zu jedem
UpperCase-Zeichen ein passendes LowerCase-Zeichen existiert.

Solche "Optimierungen" auf Basis falscher Vorstellungen und nicht
verifzierter Annahmen sind die Ursache, weshalb bis heute kaum eine
Software existiert, die fehlerfrei internationalisiert ist.

cu
Hubert Partl
2007-09-28 13:32:33 UTC
Permalink
tun wÃŒrden, denn sie basieren auf der falschen Annahme, dass zu jedem
UpperCase-Zeichen ein passendes LowerCase-Zeichen existiert.
... und dass diese Zuordnung, wenn sie existiert, eindeutig sei,
was auch nicht stimmt:

scharfes s -> SS
und ss -> SS

franzoesiche Kleinbuchstaben mit Akzent -> Grossbuchstabe ohne Akzent
und Kleinbuchstabe ohne Akzent -> Grossbuchstabe ohne Akzent

--
Bernd Post
2007-09-28 13:46:42 UTC
Permalink
Post by Hubert Partl
tun wÃŒrden, denn sie basieren auf der falschen Annahme, dass zu jedem
UpperCase-Zeichen ein passendes LowerCase-Zeichen existiert.
... und dass diese Zuordnung, wenn sie existiert, eindeutig sei,
scharfes s -> SS
und ss -> SS
franzoesiche Kleinbuchstaben mit Akzent -> Grossbuchstabe ohne Akzent
und Kleinbuchstabe ohne Akzent -> Grossbuchstabe ohne Akzent
Soweit ich weiss wird das große Szet demnächst in ISO-10646 kommen ...

SCNR
Bernd
Hubert Partl
2007-10-01 10:50:05 UTC
Permalink
Soweit ich weiss wird das groe Szet demnchst in ISO-10646 kommen ...
... und ich hoffe sehr, es wird so aussehen, wie Norbert Schwarz und
ein paar weitere "TeXperte"n auf der Rueckfahrt von einem sehr ueppigen
und auch keineswegs alkoholfreien Abend-Buffet in einem Autobus
bei der TeX-Konferenz in Cork vor rund 30 Jahren (ich sass auch dabei)
es erfunden haben:

Ein Zeichen, das gleich hoch wie ein "S" und
doppelt so breit wie ein "S" ist
und dessen graphische Linienfuehrung wie "SS" aussieht.

(In TeX muss das Uppercase ein Character sein und darf nicht,
wie in Java, ein String sein, aber einen solchen Character mit MetaFont
zu definieren, war ÃŒberhaupt kein Problem, sobald die Idee da war.)

Aber wenn ich mir so die vielen hand- oder PC-geschriebenen Schilder
ansehe,
dann wird es doch eher wie eine Mischung aus Beta und B aussehen. :-(

--

Hubert Partl
2007-09-27 12:24:48 UTC
Permalink
Post by Andreas Eberhöfer
public static void hatGrossbuchstaben(String s)
public static boolean hatGrossbuchstaben(String s)
Post by Andreas Eberhöfer
{
for(int i=0;i<s.length();i++)
{
char c = s.charAt(i);
if(Charcater.isUpperCase(c))
return true;
}
return false;
Post by Andreas Eberhöfer
}
Abgesehen von meinen kleinen Korrekturen:

Diese Loesung ist von den bisher vorgeschlagenen die effizienteste,
das zeigt sich insbesondere fÃŒr den Fall,
dass schon das erste Zeichen ein Grossbuchstabe ist.

--
Andreas Eberhöfer
2007-09-27 12:30:23 UTC
Permalink
Post by Hubert Partl
Post by Andreas Eberhöfer
public static void hatGrossbuchstaben(String s)
public static boolean hatGrossbuchstaben(String s)
Post by Andreas Eberhöfer
{
for(int i=0;i<s.length();i++)
{
char c = s.charAt(i);
if(Charcater.isUpperCase(c))
return true;
}
return false;
Post by Andreas Eberhöfer
}
Diese Loesung ist von den bisher vorgeschlagenen die effizienteste,
das zeigt sich insbesondere fÃŒr den Fall,
dass schon das erste Zeichen ein Grossbuchstabe ist.
Stimmt, das war mein Fehler. Danke für die Korrektur.

mfg
Andreas
Christoph Dahlen
2007-09-27 12:55:31 UTC
Permalink
Post by Hubert Partl
public static boolean hatGrossbuchstaben(String s)
Post by Andreas Eberhöfer
{
for(int i=0;i<s.length();i++)
{
char c = s.charAt(i);
if(Charcater.isUpperCase(c))
return true;
}
return false;
Post by Andreas Eberhöfer
}
Diese Loesung ist von den bisher vorgeschlagenen die effizienteste,
das zeigt sich insbesondere fÃŒr den Fall,
dass schon das erste Zeichen ein Grossbuchstabe ist.
Ist das so? Wird nicht auch .equals() bei der ersten
Nicht-Übereinstimmung abbrechen?

Gruß,

Christoph
Bernd Post
2007-09-27 13:05:52 UTC
Permalink
Post by Christoph Dahlen
Post by Hubert Partl
public static boolean hatGrossbuchstaben(String s)
Post by Andreas Eberhöfer
{
for(int i=0;i<s.length();i++)
{
char c = s.charAt(i);
if(Charcater.isUpperCase(c))
return true;
}
return false;
Post by Andreas Eberhöfer
}
Diese Loesung ist von den bisher vorgeschlagenen die effizienteste,
das zeigt sich insbesondere fÃŒr den Fall,
dass schon das erste Zeichen ein Grossbuchstabe ist.
Ist das so? Wird nicht auch .equals() bei der ersten
Nicht-Übereinstimmung abbrechen?
Gruß,
Christoph
Ich seh hier bisher eigentlich nur einen Beitrag in dem equals verwendet
wird ( <***@57g2000hsv.googlegroups.com> ), und
dort wird erstmal der gesamte String gelowert, braucht also bei Länge n
mindestens n Tests auf Uppercase plus einem equals Vergleich des
gesamten Strings (Der dann natürlich ggf. früh abbrechen kann)...
Performant klingt das für mich nicht.

Grüße
Bernd
d***@googlemail.com
2007-09-27 13:23:06 UTC
Permalink
Post by Bernd Post
Post by Christoph Dahlen
Post by Hubert Partl
public static boolean hatGrossbuchstaben(String s)
Post by Andreas Eberhöfer
{
for(int i=0;i<s.length();i++)
{
char c = s.charAt(i);
if(Charcater.isUpperCase(c))
return true;
}
return false;
Post by Andreas Eberhöfer
}
Diese Loesung ist von den bisher vorgeschlagenen die effizienteste,
das zeigt sich insbesondere für den Fall,
dass schon das erste Zeichen ein Grossbuchstabe ist.
Ist das so? Wird nicht auch .equals() bei der ersten
Nicht-Übereinstimmung abbrechen?
Da muss ich dir recht geben.
Post by Bernd Post
Post by Christoph Dahlen
Gruß,
Christoph
Ich seh hier bisher eigentlich nur einen Beitrag in dem equals verwendet
dort wird erstmal der gesamte String gelowert, braucht also bei Länge n
mindestens n Tests auf Uppercase plus einem equals Vergleich des
gesamten Strings (Der dann natürlich ggf. früh abbrechen kann)...
Performant klingt das für mich nicht.
Grüße
Bernd
Ralf Ullrich
2007-09-27 14:06:35 UTC
Permalink
Post by Hubert Partl
Post by Andreas Eberhöfer
public static void hatGrossbuchstaben(String s)
public static boolean hatGrossbuchstaben(String s)
Post by Andreas Eberhöfer
{
for(int i=0;i<s.length();i++)
{
char c = s.charAt(i);
if(Charcater.isUpperCase(c))
return true;
}
return false;
Post by Andreas Eberhöfer
}
Diese Loesung ist von den bisher vorgeschlagenen die effizienteste,
Effizient vielleicht.

Korrekt leider nicht! (Oder wenn, dann nur bis nur bis Java 1.4 und somit
Unicode <4.0)

Hier wie es wirklich korrekt geht:

public static boolean hasUpperCaseCharacters(String s) {
int pos = 0;
while (pos < s.length()) {
int cp = s.codePointAt(pos);
if (Character.isUpperCase(cp)) {
return true;
}
pos += Character.charCount(cp);
}
return false;
}

cu
Stefan Matthias Aust
2007-09-27 16:55:46 UTC
Permalink
Post by Ralf Ullrich
Effizient vielleicht.
Korrekt leider nicht!
Man kann auch päpstlicher sein als der Papst. Der "Trick an UTF-16" ist,
dass die Zeichen U+010000 bis U+10FFFF, die nicht mehr in nur 16 Bit
passen, derart kodiert werden, dass sie in 0xD800-0xDFFF liegen, was in
älteren Unicode-Versionen frei war - damit liegen in diesen Bereichen
niemals uppercase oder lowercase letters. Ich halte es daher für
durchaus korrekt und effizient, einfach char für char den String zu
iterieren.
--
Stefan Matthias Aust
Ralf Ullrich
2007-09-27 17:09:25 UTC
Permalink
Post by Stefan Matthias Aust
Post by Ralf Ullrich
Effizient vielleicht.
Korrekt leider nicht!
Man kann auch päpstlicher sein als der Papst. Der "Trick an UTF-16" ist,
dass die Zeichen U+010000 bis U+10FFFF, die nicht mehr in nur 16 Bit
passen, derart kodiert werden, dass sie in 0xD800-0xDFFF liegen, was in
älteren Unicode-Versionen frei war - damit liegen in diesen Bereichen
niemals uppercase oder lowercase letters.
In diesen Bereich nicht, aber dennoch kann ein Surrogatpaar einen Upper-
oder Lowercase Supplementary-Character repräsentieren. Du musst also um
korrekt zu sein, den Codepoint testen, weil du durchs testen der beiden
Surrogat-Werte die Information eben nicht erhältst.
Post by Stefan Matthias Aust
Ich halte es daher für
durchaus korrekt und effizient, einfach char für char den String zu
iterieren.
Ich nicht und mich wundert so eine Aussage ausgerechnet von dir, du
müsstest es besser wissen.

cu
Stefan Matthias Aust
2007-09-27 17:40:50 UTC
Permalink
Post by Ralf Ullrich
In diesen Bereich nicht, aber dennoch kann ein Surrogatpaar einen Upper-
oder Lowercase Supplementary-Character repräsentieren. Du musst also um
korrekt zu sein, den Codepoint testen, weil du durchs testen der beiden
Surrogat-Werte die Information eben nicht erhältst.
Hast du mal ein Beispiel für mich, denn ich weiß es (auch wenn du dich
wunderst ;) es leider nicht besser. Gibt es Großbuchstaben mit einem
Codepoint >= U+10000?
--
Stefan Matthias Aust
Ralf Ullrich
2007-09-27 17:53:15 UTC
Permalink
Post by Stefan Matthias Aust
Hast du mal ein Beispiel für mich, denn ich weiß es (auch wenn du dich
wunderst ;) es leider nicht besser. Gibt es Großbuchstaben mit einem
Codepoint >= U+10000?
Als ob du das nicht selbst rausfinden könntest:

public static void main(String[] args) {
for (int cp = Character.MIN_CODE_POINT; cp <= Character.MAX_CODE_POINT;
cp++) {
if (Character.isSupplementaryCodePoint(cp) && (Character.isUpperCase(cp))) {
String uc = new String(Character.toChars(cp));
String lc = uc.toLowerCase();
boolean hasDifferentLower = uc.equals(lc);
System.out.println(Integer.toHexString(cp) + (hasDifferentLower ? " is a upper case supplementary"
: " is a upper case supplementary but has no lower case"));
}
}
}

cu
Stefan Matthias Aust
2007-09-27 18:13:34 UTC
Permalink
Als ob du das nicht selbst rausfinden könntest: [...]
Fragen ist einfacher, als sich ein Java zu besorgen ;) Mir war nicht
bewusst, dass jenseits von U+10000 noch Dinge wie z.B. "Deseret", ein um
1850 entwickeltes Alphabet der Mormonen lagern. Damit hast du Recht, man
muss die Strings codepoint für codepoint ablaufen, nicht char für char.

In der Hoffnung (ohne das jetzt zu prüfen), dass reguläre Ausdrücke das
richtig machen, würde ich also einen solchen bemühen und nicht eine
for-Schleife benutzen.
--
Stefan Matthias Aust
Andreas Schüle
2007-09-27 11:25:32 UTC
Permalink
Hi,

ich stelle mir die L=F6sung wie folgt vor...

public boolean hasUpperCaseCharacters(String str) {
String tmp =3D str.toLowerCase();

for (int i =3D 0; i<str.length(); i++) {
if (str.charAt(i) !=3D tmp.charAt(i)) {
return true;
}
}
return false;
}

Gru=DF,

Andreas
Post by m***@gmx.de
Hallo,
ich m=F6chte =FCberpr=FCfen, ob ein String mindestens einen Gro=DFbuch=
staben
Post by m***@gmx.de
enth=E4lt. Wie kann ich das tun? Regul=E4re Ausdr=FCcke?
Danke im Voraus,
David
-- =

Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Robert Mahnke
2007-09-27 12:28:02 UTC
Permalink
Hallo David,
Post by m***@gmx.de
ich möchte überprüfen, ob ein String mindestens einen Großbuchstaben
enthält. Wie kann ich das tun? Reguläre Ausdrücke?
ginge mit Regex so:

Pattern p = Pattern.compile( ".*\\p{Upper}.*" );
Matcher m = p.matcher( "malsehenobinmirGrossbuchstabensind" );
boolean b = m.matches();

Gruß
Robert
Stefan Matthias Aust
2007-09-27 17:05:13 UTC
Permalink
Post by Robert Mahnke
Pattern p = Pattern.compile( ".*\\p{Upper}.*" );
Matcher m = p.matcher( "malsehenobinmirGrossbuchstabensind" );
boolean b = m.matches();
Statt mit "*" den String aufzufüllen (was Backtracking erfordert),
besser das API ausnutzen:

Pattern p = Pattern.compile(\\p{Upper}");
Matcher m = p.matcher("...");
boolean b = m.find();
--
Stefan Matthias Aust
Ralf Ullrich
2007-09-27 18:32:32 UTC
Permalink
Post by Stefan Matthias Aust
Pattern p = Pattern.compile(\\p{Upper}");
Ich antworte mal hier, obwohl es eine Rück-Antwort zu deinem anderen
Antwort-Posting an mich ist.

\p{Upper}

ist US-ASCII only, also sogar noch schlimmer als chars statt codepoints.

Die Unicode Category wäre

\p{Lu}

(Alle weiteren findet man hier:
http://unicode.org/Public/UNIDATA/UCD.html#General_Category_Values )

Ach um noch deine implizite Frage zu beantworten: Laut Doku unterstützen
Javas RegEx die Supplementary Characters, da sie den Level 1
Unicode-RegEx-Guidelines nach dem Standard folgen. (
http://www.unicode.org/reports/tr18/#Supplementary_Characters )
Loading...