Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Whether or not regular expressions are well suited for this task is debatable. Most people would probably argue that it's not.</p> <p>As I understand it however, you have no choice as the API you're using takes a regular expression as argument, so here goes...</p> <h2>Code</h2> <pre><code>public class NumericRangeRegexGenerator { private static String baseRange(String num, boolean up, boolean leading1) { char c = num.charAt(0); char low = up ? c : leading1 ? '1' : '0'; char high = up ? '9' : c; if (num.length() == 1) return charClass(low, high); String re = c + "(" + baseRange(num.substring(1), up, false) + ")"; if (up) low++; else high--; if (low &lt;= high) re += "|" + charClass(low, high) + nDigits(num.length() - 1); return re; } private static String charClass(char b, char e) { return String.format(b==e ? "%c" : e-b&gt;1 ? "[%c-%c]" : "[%c%c]", b, e); } private static String nDigits(int n) { return nDigits(n, n); } private static String nDigits(int n, int m) { return "[0-9]" + String.format(n==m ? n==1 ? "":"{%d}":"{%d,%d}", n, m); } private static String eqLengths(String from, String to) { char fc = from.charAt(0), tc = to.charAt(0); if (from.length() == 1 &amp;&amp; to.length() == 1) return charClass(fc, tc); if (fc == tc) return fc + "("+rangeRegex(from.substring(1), to.substring(1))+")"; String re = fc + "(" + baseRange(from.substring(1), true, false) + ")|" + tc + "(" + baseRange(to.substring(1), false, false) + ")"; if (++fc &lt;= --tc) re += "|" + charClass(fc, tc) + nDigits(from.length() - 1); return re; } private static String nonEqLengths(String from, String to) { String re = baseRange(from,true,false) + "|" + baseRange(to,false,true); if (to.length() - from.length() &gt; 1) re += "|[1-9]" + nDigits(from.length(), to.length() - 2); return re; } public static String rangeRegex(int n, int m) { return rangeRegex("" + n, "" + m); } public static String rangeRegex(String n, String m) { return n.length() == m.length() ? eqLengths(n, m) : nonEqLengths(n, m); } } </code></pre> <h3>Usage</h3> <pre><code>// Generate expression for range 123 - 321 String regexp = NumericRangeRegexGenerator.rangeRegex(123, 321); </code></pre> <p><br/></p> <h2>Explanation</h2> <p>A brief explanation of the code follows.</p> <h3>Ranges on the shape <code>0000</code>-<code>abcd</code> and <code>abcd</code>-<code>9999</code></h3> <p>First we note that matching ranges such as <code>0000</code>-<code>abcd</code> is fairly easy.</p> <p>An expression covering for instance <code>000</code>-<code>527</code> can be expressed as</p> <ul> <li><code>[0-4]</code> followed by two arbitrary digits, or</li> <li><code>5</code> followed by <code>00</code>-<code>27</code> (which is resolved recursively!)</li> </ul> <p>Ranges on the shape <code>1000</code>-<code>abcd</code> and <code>abcd</code>-<code>9999</code> are just as easy.</p> <h3>Lower limit, upper limit of different lengths.</h3> <p>If the "from"-number is shorter than the "to"-number it is fairly straight forward.</p> <p>Assume for instance that the <code>from</code>-number has 3 digits and the <code>to</code>-number has 7 digits. The expression can then be composed as follows:</p> <ul> <li><code>from</code>-<code>999</code> (as described above),</li> <li>Any <code>4</code>, <code>5</code> or <code>6</code> digit number: <code>[1-9][0-9]{3-5}</code>, or</li> <li><code>1000000</code>-<code>to</code> (as described above)</li> </ul> <h3>Lower limit / upper limit of equal lengths.</h3> <p>This is the trickiest situation (still not <em>that</em> tricky though!)</p> <p>The solution is, again, best described by an example. Consider the range <code>273</code> - <code>548</code>. The expression can be composed by the following parts:</p> <ul> <li><code>2</code> followed by <code>73</code>-<code>99</code> (latter part described above),</li> <li><code>[34]</code> followed by any two digits, or</li> <li><code>5</code> followed by <code>00</code>-<code>48</code> (latter part described above)</li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload