<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://unkrig.de/w/index.php?action=history&amp;feed=atom&amp;title=Using_Globs</id>
	<title>Using Globs - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://unkrig.de/w/index.php?action=history&amp;feed=atom&amp;title=Using_Globs"/>
	<link rel="alternate" type="text/html" href="https://unkrig.de/w/index.php?title=Using_Globs&amp;action=history"/>
	<updated>2026-05-11T13:48:08Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.1</generator>
	<entry>
		<id>https://unkrig.de/w/index.php?title=Using_Globs&amp;diff=41&amp;oldid=prev</id>
		<title>Admin: Created page with &quot;This article documents the &quot;Globs&quot; feature implemented in [http://commons.unkrig.de/commons-text/apidocs/index.html?de/unkrig/commons/text/pattern/package-summary.html commons.unkrig.de].  === Introduction ===  Surely you have used globs before (maybe even without knowing that they call them &quot;globs&quot;):   *.txt  dir/*.doc  execut?r.txt  Globs are a widely spread concept that is used throughout the UNIX, MICROSOFT and other &quot;worlds&quot;.  All implementations support at least th...&quot;</title>
		<link rel="alternate" type="text/html" href="https://unkrig.de/w/index.php?title=Using_Globs&amp;diff=41&amp;oldid=prev"/>
		<updated>2024-05-01T20:18:28Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;This article documents the &amp;quot;Globs&amp;quot; feature implemented in [http://commons.unkrig.de/commons-text/apidocs/index.html?de/unkrig/commons/text/pattern/package-summary.html commons.unkrig.de].  === Introduction ===  Surely you have used globs before (maybe even without knowing that they call them &amp;quot;globs&amp;quot;):   *.txt  dir/*.doc  execut?r.txt  Globs are a widely spread concept that is used throughout the UNIX, MICROSOFT and other &amp;quot;worlds&amp;quot;.  All implementations support at least th...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;This article documents the &amp;quot;Globs&amp;quot; feature implemented in [http://commons.unkrig.de/commons-text/apidocs/index.html?de/unkrig/commons/text/pattern/package-summary.html commons.unkrig.de].&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Surely you have used globs before (maybe even without knowing that they call them &amp;quot;globs&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
 *.txt&lt;br /&gt;
 dir/*.doc&lt;br /&gt;
 execut?r.txt&lt;br /&gt;
&lt;br /&gt;
Globs are a widely spread concept that is used throughout the UNIX, MICROSOFT and other &amp;quot;worlds&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
All implementations support at least the following elements:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Construct     !!Matches&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;    ||Any character except the file separator (&amp;quot;&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;&amp;quot; and/or &amp;quot;&amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt;&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;    ||Zero or more characters except the file separator&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;#039;&amp;#039;x&amp;#039;&amp;#039;&amp;lt;/tt&amp;gt;||The character &amp;lt;tt&amp;gt;&amp;#039;&amp;#039;x&amp;#039;&amp;#039;&amp;lt;/tt&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Some implementations add more features:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Construct                                   !!Matches&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[abc]&amp;lt;/tt&amp;gt;                              ||Exactly one of the characters &amp;quot;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&amp;quot;, &amp;quot;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;&amp;quot; and &amp;quot;&amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[^abc]&amp;lt;/tt&amp;gt;&amp;lt;br /&amp;gt;or&amp;lt;br /&amp;gt;&amp;lt;tt&amp;gt;[!abc]&amp;lt;/tt&amp;gt;||Any character &amp;#039;&amp;#039;except&amp;#039;&amp;#039; &amp;quot;&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&amp;quot;, &amp;quot;&amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt;&amp;quot; or &amp;quot;&amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;[A-Za-z]&amp;lt;/tt&amp;gt;                           ||Any (latin) letter&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;**&amp;lt;/tt&amp;gt;                                 ||Zero or more characters (&amp;#039;&amp;#039;including&amp;#039;&amp;#039; the file separator)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;\&amp;#039;&amp;#039;X&amp;#039;&amp;#039;&amp;lt;/tt&amp;gt;                             ||&amp;quot;&amp;lt;tt&amp;gt;&amp;#039;&amp;#039;X&amp;#039;&amp;#039;&amp;lt;/tt&amp;gt;&amp;quot;, even if &amp;quot;&amp;lt;tt&amp;gt;&amp;#039;&amp;#039;X&amp;#039;&amp;#039;&amp;lt;/tt&amp;gt;&amp;quot; is a meta character&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Since version 1.7 JAVA provides [http://docs.oracle.com/javase/7/docs/api/java/nio/file/FileSystem.html#getPathMatcher%28java.lang.String%29 its own implementation] of &amp;quot;glob matching&amp;quot;, which adds another (quite uncommon) construct:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Construct                              !!Matches&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;{&amp;#039;&amp;#039;alpha&amp;#039;&amp;#039;,&amp;#039;&amp;#039;beta&amp;#039;&amp;#039;,&amp;#039;&amp;#039;gamma&amp;#039;&amp;#039;}&amp;lt;/tt&amp;gt;||Any of &amp;quot;&amp;lt;tt&amp;gt;alpha&amp;lt;/tt&amp;gt;&amp;quot;, &amp;quot;&amp;lt;tt&amp;gt;beta&amp;lt;/tt&amp;gt;&amp;quot; or &amp;quot;&amp;lt;tt&amp;gt;gamma&amp;lt;/tt&amp;gt;&amp;quot;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
All in all, globs are very practical, though not very powerful. This is why &amp;lt;code&amp;gt;de.unkrig.commons&amp;lt;/code&amp;gt; provides yet another implementation, as follows:&lt;br /&gt;
&lt;br /&gt;
=== Regular expressions features ===&lt;br /&gt;
&lt;br /&gt;
First,&lt;br /&gt;
[http://commons.unkrig.de/commons-text/apidocs/index.html?de/unkrig/commons/text/pattern/Pattern2.html &amp;lt;code&amp;gt;de.unkrig.commons.text.pattern.Pattern2&amp;lt;/code&amp;gt;]&lt;br /&gt;
combines the simplicity of globs with the full power of&lt;br /&gt;
[http://docs.oracle.com/javase/7/docs/api/index.html?java/util/regex/Pattern.html JAVA regular expressions].&lt;br /&gt;
It does so by modifying a few characters in the glob before feeding it to &amp;lt;code&amp;gt;java.util.text.pattern.Pattern.compile()&amp;lt;/code&amp;gt;, making that effectively a glob compiler:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Glob construct!!Regex construct  !!Matches&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;    ||&amp;lt;tt&amp;gt;[^/\\!]*&amp;lt;/tt&amp;gt;||Any character except the file separator and &amp;quot;!&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;    ||&amp;lt;tt&amp;gt;[^/\\!]*&amp;lt;/tt&amp;gt;||Zero or more characters except the file separator and &amp;quot;!&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;**&amp;lt;/tt&amp;gt;   ||&amp;lt;tt&amp;gt;[^!]*&amp;lt;/tt&amp;gt;   ||Zero or more characters except &amp;quot;!&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;***&amp;lt;/tt&amp;gt;  ||&amp;lt;tt&amp;gt;.*&amp;lt;/tt&amp;gt;      ||Zero or more characters&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;.&amp;lt;/tt&amp;gt;||&amp;lt;tt&amp;gt;\.&amp;lt;/tt&amp;gt;||The dot is a literal (not a character class as in a regular expression)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
If you have not yet worked with regular expressions: JAVA regular expressions are very powerful and introduce many constructs and meta characters. Find the complete reference documentation [http://docs.oracle.com/javase/7/docs/api/index.html?java/util/regex/Pattern.html here].&lt;br /&gt;
&lt;br /&gt;
Since &amp;quot;&amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;&amp;quot; and &amp;quot;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;&amp;quot; are not quantifiers as in regular expression (&amp;quot;&amp;lt;tt&amp;gt;?&amp;lt;/tt&amp;gt;&amp;quot; == zero-or-one, &amp;quot;&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;&amp;quot; == zero-or-more), one has to use &amp;quot;&amp;lt;tt&amp;gt;{0,1}&amp;lt;/tt&amp;gt;&amp;quot; and &amp;quot;&amp;lt;tt&amp;gt;{0,}&amp;lt;/tt&amp;gt;&amp;quot; instead. The alternative notation for &amp;quot;&amp;lt;tt&amp;gt;.&amp;lt;/tt&amp;gt;&amp;quot; (&amp;quot;any character&amp;quot;) is &amp;quot;&amp;lt;tt&amp;gt;[^]&amp;lt;/tt&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Find the reference documentation [http://commons.unkrig.de/javadoc/index.html?de/unkrig/commons/text/pattern/Pattern2.html here].&lt;br /&gt;
&lt;br /&gt;
The API of&lt;br /&gt;
[http://commons.unkrig.de/commons-text/apidocs/index.html?de/unkrig/commons/text/pattern/Pattern2.html &amp;lt;code&amp;gt;de.unkrig.commons.text.pattern.Pattern2&amp;lt;/code&amp;gt;]&lt;br /&gt;
is totally compatible with that of&lt;br /&gt;
[http://docs.oracle.com/javase/7/docs/api/index.html?java/util/regex/Pattern.html &amp;lt;code&amp;gt;java.util.pattern.Pattern&amp;lt;/code&amp;gt;],&lt;br /&gt;
plus it adds a new compilation Flag &amp;lt;code&amp;gt;Pattern2.WILDCARD&amp;lt;/code&amp;gt; that modifies the expression syntax from regex to globs.&lt;br /&gt;
&lt;br /&gt;
=== Includes-Excludes ===&lt;br /&gt;
&lt;br /&gt;
Second, it adds &amp;#039;&amp;#039;includes-excludes&amp;#039;&amp;#039;. This involves two new meta characters, &amp;quot;&amp;lt;code&amp;gt;,&amp;lt;/code&amp;gt;&amp;quot; and &amp;quot;&amp;lt;code&amp;gt;~&amp;lt;/code&amp;gt;&amp;quot;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Construct                         !!Matches&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;#039;&amp;#039;pattern1&amp;#039;&amp;#039;,&amp;#039;&amp;#039;pattern2&amp;#039;&amp;#039;&amp;lt;/tt&amp;gt;||Any string that matches &amp;#039;&amp;#039;pattern1&amp;#039;&amp;#039; or &amp;#039;&amp;#039;pattern2&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;#039;&amp;#039;pattern1&amp;#039;&amp;#039;~&amp;#039;&amp;#039;pattern2&amp;#039;&amp;#039;&amp;lt;/tt&amp;gt;||Any string that matches &amp;#039;&amp;#039;pattern1&amp;#039;&amp;#039;, but not &amp;#039;&amp;#039;pattern2&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;~&amp;#039;&amp;#039;pattern1&amp;#039;&amp;#039;&amp;lt;/tt&amp;gt;            ||Any string that does &amp;#039;&amp;#039;not&amp;#039;&amp;#039; match &amp;#039;&amp;#039;pattern1&amp;#039;&amp;#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;&amp;#039;&amp;#039;pattern1&amp;#039;&amp;#039;,&amp;#039;&amp;#039;pattern2&amp;#039;&amp;#039;~&amp;#039;&amp;#039;pattern3&amp;#039;&amp;#039;~&amp;#039;&amp;#039;pattern4&amp;#039;&amp;#039;,&amp;#039;&amp;#039;pattern5&amp;#039;&amp;#039;&amp;lt;/tt&amp;gt;||Any string that matches &amp;#039;&amp;#039;pattern1&amp;#039;&amp;#039; or &amp;#039;&amp;#039;pattern2&amp;#039;&amp;#039;, but not &amp;#039;&amp;#039;pattern3&amp;#039;&amp;#039; nor &amp;#039;&amp;#039;pattern4&amp;#039;&amp;#039;; plus any string that matches &amp;#039;&amp;#039;pattern5&amp;#039;&amp;#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This may sound complicated, but the very simple rule is: The patterns are applied &amp;#039;&amp;#039;right-to-left&amp;#039;&amp;#039;, and the first match determines the result.&lt;br /&gt;
&lt;br /&gt;
This comes with [http://commons.unkrig.de/javadoc/index.html?de/unkrig/commons/text/pattern/Glob.html &amp;lt;tt&amp;gt;de.unkrig.commons.text.pattern.Glob.compile()&amp;lt;/tt&amp;gt;] and the new [http://commons.unkrig.de/javadoc/index.html?de/unkrig/commons/text/pattern/Glob.html &amp;lt;tt&amp;gt;INCLUDES_EXCLUDES&amp;lt;/tt&amp;gt;] compilation flag.&lt;br /&gt;
&lt;br /&gt;
=== Replacements ===&lt;br /&gt;
&lt;br /&gt;
Third, it adds &amp;#039;&amp;#039;replacements&amp;#039;&amp;#039;. This involves one new meta character, &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Construct               !!Matches                             !!Replaces with&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;*.c=$0.bak&amp;lt;/tt&amp;gt;     ||Any string ending with &amp;quot;&amp;lt;tt&amp;gt;.c&amp;lt;/tt&amp;gt;&amp;quot;||The original string plus &amp;quot;&amp;lt;tt&amp;gt;.bak&amp;lt;/tt&amp;gt;&amp;quot; (&amp;quot;&amp;lt;tt&amp;gt;$0&amp;lt;/tt&amp;gt;&amp;quot; represents the &amp;quot;entire match&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;tt&amp;gt;(*).(*)=$1.$2$2&amp;lt;/tt&amp;gt;||Any string containing a dot         ||The original string, with the file name extension doubled&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This comes with the [http://commons.unkrig.de/javadoc/index.html?de/unkrig/commons/text/pattern/Glob.html &amp;lt;tt&amp;gt;Glob.replace()&amp;lt;/tt&amp;gt;] API.&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;quot;&amp;lt;tt&amp;gt;$&amp;lt;/tt&amp;gt;&amp;quot; is a meta character &amp;#039;&amp;#039;only in the replacement&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Also notice that when combining replacements with includes-excludes (see above), replacements are specific for &amp;#039;&amp;#039;each&amp;#039;&amp;#039; include (while it does not make any sense to use replacements with excludes, though).&lt;br /&gt;
&lt;br /&gt;
=== Conclusion ===&lt;br /&gt;
&lt;br /&gt;
All these features can be combined mercilessly, e.g.:&lt;br /&gt;
&lt;br /&gt;
 *=$0$0~*.bak&lt;br /&gt;
 (*).docx{0,1}=$1.txt~*blabla*&lt;br /&gt;
&lt;br /&gt;
Using it is simple:&lt;br /&gt;
&lt;br /&gt;
 import de.unkrig.commons.text.pattern.Glob;&lt;br /&gt;
 import de.unkrig.commons.text.pattern.Pattern2;&lt;br /&gt;
 &lt;br /&gt;
 Glob glob = Glob.compile(&amp;quot;*.c=$0.C,*.h=$0.H&amp;quot;, Pattern2.WILDCARD | Glob.INCLUDES_EXCLUDES | Glob.REPLACEMENT);&lt;br /&gt;
 glob.match(&amp;quot;foo.c&amp;quot;);     // returns true&lt;br /&gt;
 glob.replace(&amp;quot;foo.h&amp;quot;);   // returns &amp;quot;foo.H&amp;quot;&lt;br /&gt;
 glob.replace(&amp;quot;foo.cpp&amp;quot;); // returns null&lt;br /&gt;
&lt;br /&gt;
Remember: The &amp;lt;tt&amp;gt;Pattern2.WILDCARD&amp;lt;/tt&amp;gt; modifies the regex compilation to understand wildcard characters. &amp;lt;tt&amp;gt;Glob.INCLUDES_EXCLUDES&amp;lt;/tt&amp;gt; activates the recognition of &amp;quot;&amp;lt;tt&amp;gt;,&amp;lt;/tt&amp;gt;&amp;quot; and &amp;quot;&amp;lt;tt&amp;gt;~&amp;lt;/tt&amp;gt;&amp;quot;. Finally, &amp;lt;tt&amp;gt;Glob.REPLACEMENT&amp;lt;/tt&amp;gt; activates the recognition of &amp;quot;&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>