{"id":3142,"date":"2015-05-23T10:25:20","date_gmt":"2015-05-23T08:25:20","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=3142"},"modified":"2015-05-23T10:25:20","modified_gmt":"2015-05-23T08:25:20","slug":"inselupdate-suchen-und-ersetzen-mit-mustern","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2015\/05\/inselupdate-suchen-und-ersetzen-mit-mustern\/","title":{"rendered":"Inselupdate: Suchen und Ersetzen mit Mustern"},"content":{"rendered":"<p>F\u00fcr den Suchfall mit Java RegEx gibt es noch eine Erweiterung, dass n\u00e4mlich die Pattern-Klasse die Fundstellen nicht nur ermittelt, sondern sie auch durch etwas anderes ersetzen kann.  <\/p>\n<p>Beispiel: In einem String sollen alle Nicht-JVM-Sprachen ausgepiept werden:  <\/p>\n<p>String&nbsp; text&nbsp;&nbsp;&nbsp; = &#8222;Ich mag Java, Groovy und ObjectiveC und PHP.&#8220;;<br \/>Matcher matcher = Pattern.compile(&#8222;ObjectiveC|PHP&#8220; ).matcher( text );<br \/>StringBuffer sb = new StringBuffer();<br \/>while ( matcher.find() )<br \/><b>matcher.appendReplacement( sb, &#8222;[PIEP]&#8220; )<\/b>;<br \/><b>matcher.appendTail( sb );<\/b><br \/>System.out.println( sb );&nbsp; \/\/ Ich mag Java, Groovy und [PIEP] und [PIEP].  <\/p>\n<p>Um mit dem Mechanismus \u201eSuchen und Ersetzen\u201c zu arbeiten, wird zun\u00e4chst ein Container vom Typ StringBuffer aufgebaut, denn in dem echten String kann Pattern die Fundstellen nicht ersetzen. (Leider ist ein StringBuffer n\u00f6tig, die API akzeptiert keinen StringBuilder.) Erkennt der Matcher ein Muster, macht appendReplacement(\u2026) zwei Dinge:  <\/p>\n<p>1. Die Methode f\u00fcllt den Container mit allen Zeichen vom letzten Fund bis zur jetzigen Fundstelle auf. Beim ersten Aufruf ist das \u201eIch mag Java, Groovy und \u201c, dann folgt \u201e und \u201c.  <\/p>\n<p>2. In den StringBuffer k\u00f6nnen wir unsere Ersetzung, in diesem Falle \u201e[PIEP]\u201c, setzen.  <\/p>\n<p>So w\u00e4chst der StringBuffer von Schritt zu Schritt. Nach der letzten Fundstelle setzt appendTail(\u2026) das noch verbleibende Teilst\u00fcck von der letzten Funstelle bis zum Stringende in den StringBuffer-Container.  <\/p>\n<p>Im Prinzip k\u00f6nnen wir in der while-Schleife mit matcher.group(\u2026) auf das Fundst\u00fcck zur\u00fcckgreifen und es in die Ersetzung einbauen. Doch toll an appendReplacement(\u2026) ist, dass der Ersetzungsstring ein $ enthalten darf \u2013 mit dem Problem, dass ein vorkommendes Dollar-Zeichen ausmaskiert werden muss \u2013, der Zugriff auf die Suchgruppe bietet. Damit lassen sich sehr elegante L\u00f6sungen bauen. Nehmen wir an, wir m\u00fcssen in einer Zeichenkette alle URLs in HTML-Hyperlinks konvertieren. Dann rahmen wir einfach jede Fundstelle in die n\u00f6tigen HTML-Tags ein. In Quellcode sieht das so aus:  <\/p>\n<p>Listing 2.7: RegExSearchAndReplace.java, main()  <\/p>\n<p>String&nbsp; text&nbsp;&nbsp;&nbsp; = &#8222;Hi, schau mal bei http:\/\/stackoverflow.com\/ &#8220; +<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8222;oder http:\/\/www.tutego.de\/ vorbei.&#8220;;<br \/>String&nbsp; regex&nbsp;&nbsp; = &#8222;http:\/\/[a-zA-Z0-9\\\\\\]+\\\\.[a-zA-Z]{2,3}(\\\\S*)?&#8220;;<br \/>Matcher matcher = Pattern.compile( regex ).matcher( text );<br \/>StringBuffer sb = new StringBuffer( text.length() );<br \/>while ( matcher.find() )<br \/>&nbsp; matcher.appendReplacement( sb, &#8222;&lt;a href=\\&#8220;$0\\&#8220;&gt;$0&lt;\/a&gt;&#8220; );<br \/>matcher.appendTail( sb );<br \/>System.out.println( sb );  <\/p>\n<p>Der StringBuffer enth\u00e4lt dann zum Schluss &#8222;Hi, schau mal bei &lt;a href=&#8220;http:\/\/stackoverflow.com\/&#8220;&gt;http:\/\/stackoverflow.com\/&lt;\/a&gt; oder &lt;a href=&#8220;http:\/\/www.tutego.de\/&#8220;&gt;http:\/\/www.tutego.de\/&lt;\/a&gt; vorbei.&#8220;. (Der gew\u00e4hlte regul\u00e4re Ausdruck f\u00fcr URLs ist kurz, aber nicht vollst\u00e4ndig. F\u00fcr das Beispiel spielt das aber keine Rolle.)  <\/p>\n<p>Tipp: Die String-Methoden replaceAll(\u2026) und replaceFirst(\u2026) ersetzen direkt, und arbeiten im Hintergrund genauso. Zum Einsatz kommt die replaceAll(.,.)-Methode vom Matcher.  <\/p>\n<p>Hinweis: Der Ersetzungsausdruck &#8222;&lt;a href=\\&#8220;$0\\&#8220;&gt;$0&lt;\/a&gt;&#8220; enth\u00e4lt mit $ Steuerzeichen f\u00fcr den Matcher. Wenn die Ersetzung aber \u00fcberhaupt nicht mit $n auf das gefundene Wort zur\u00fcckgreift, sollten die beiden Sonderzeichen \\ und $ ausmaskiert werden. Auf diese Weise werden merkw\u00fcrdige Fehler vermieden, wenn doch in der Ersetzung ein Dollar-Zeichen oder ein Backslash vorkommt. Das Ausmaskieren \u00fcbernimmt die Methode quoteReplacement(\u2026), sodass sich zum Beispiel Folgendes ergibt:  <\/p>\n<p>matcher.appendReplacement( sb, Matcher.quoteReplacement( replacement ) );<\/p>\n","protected":false},"excerpt":{"rendered":"<p>F\u00fcr den Suchfall mit Java RegEx gibt es noch eine Erweiterung, dass n\u00e4mlich die Pattern-Klasse die Fundstellen nicht nur ermittelt, sondern sie auch durch etwas anderes ersetzen kann. Beispiel: In einem String sollen alle Nicht-JVM-Sprachen ausgepiept werden: String&nbsp; text&nbsp;&nbsp;&nbsp; = &#8222;Ich mag Java, Groovy und ObjectiveC und PHP.&#8220;;Matcher matcher = Pattern.compile(&#8222;ObjectiveC|PHP&#8220; ).matcher( text );StringBuffer sb [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[11],"tags":[],"class_list":["post-3142","post","type-post","status-publish","format-standard","hentry","category-insel"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/3142","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=3142"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/3142\/revisions"}],"predecessor-version":[{"id":3143,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/3142\/revisions\/3143"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=3142"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=3142"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=3142"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}