Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I think something like this is what you want.</p> <p>For alternating characters:</p> <pre><code>(?=(.)(?!\1)(.))(?:\1\2){2,} </code></pre> <p><code>\0</code> will be the entire alternating sequence, <code>\1</code> and <code>\2</code> are the two (distinct) alternating characters.</p> <p>For run of N and M characters, possibly separated by other characters (replace <code>N</code> and <code>M</code> with numbers here):</p> <pre><code>(?=(.))\1{N}.*?(?=(?!\1)(.))\2{M} </code></pre> <p><code>\0</code> will be entire match, including infix. <code>\1</code> is the character repeated (at least) <code>N</code> times, <code>\2</code> is the character repeated (at least) <code>M</code> times.</p> <p>Here's a test harness in Java.</p> <pre><code>import java.util.regex.*; public class Regex3 { static String runNrunM(int N, int M) { return "(?=(.))\\1{N}.*?(?=(?!\\1)(.))\\2{M}" .replace("N", String.valueOf(N)) .replace("M", String.valueOf(M)); } static void dumpMatches(String text, String pattern) { Matcher m = Pattern.compile(pattern).matcher(text); System.out.println(text + " &lt;- " + pattern); while (m.find()) { System.out.println(" match"); for (int g = 0; g &lt;= m.groupCount(); g++) { System.out.format(" %d: [%s]%n", g, m.group(g)); } } } public static void main(String[] args) { String[] tests = { "foobababababaf foobaafoobaaaooo", "xxyyyy axxayyyya zzzzzzzzzzzzzz" }; for (String test : tests) { dumpMatches(test, "(?=(.)(?!\\1)(.))(?:\\1\\2){2,}"); } for (String test : tests) { dumpMatches(test, runNrunM(3, 3)); } for (String test : tests) { dumpMatches(test, runNrunM(2, 4)); } } } </code></pre> <p>This produces the following output:</p> <pre><code>foobababababaf foobaafoobaaaooo &lt;- (?=(.)(?!\1)(.))(?:\1\2){2,} match 0: [bababababa] 1: [b] 2: [a] xxyyyy axxayyyya zzzzzzzzzzzzzz &lt;- (?=(.)(?!\1)(.))(?:\1\2){2,} foobababababaf foobaafoobaaaooo &lt;- (?=(.))\1{3}.*?(?=(?!\1)(.))\2{3} match 0: [aaaooo] 1: [a] 2: [o] xxyyyy axxayyyya zzzzzzzzzzzzzz &lt;- (?=(.))\1{3}.*?(?=(?!\1)(.))\2{3} match 0: [yyyy axxayyyya zzz] 1: [y] 2: [z] foobababababaf foobaafoobaaaooo &lt;- (?=(.))\1{2}.*?(?=(?!\1)(.))\2{4} xxyyyy axxayyyya zzzzzzzzzzzzzz &lt;- (?=(.))\1{2}.*?(?=(?!\1)(.))\2{4} match 0: [xxyyyy] 1: [x] 2: [y] match 0: [xxayyyy] 1: [x] 2: [y] </code></pre> <hr> <h3>Explanation</h3> <ul> <li><code>(?=(.)(?!\1)(.))(?:\1\2){2,}</code> has two parts <ul> <li><code>(?=(.)(?!\1)(.))</code> establishes <code>\1</code> and <code>\2</code> using lookahead <ul> <li>Nested negative lookahead ensures that <code>\1</code> != <code>\2</code></li> <li>Using lookahead to capture lets <code>\0</code> have the entire match (instead of just the "tail" end)</li> </ul></li> <li><code>(?:\1\2){2,}</code> captures the <code>\1\2</code> sequence, which must repeat at least twice.</li> </ul></li> <li><code>(?=(.))\1{N}.*?(?=(?!\1)(.))\2{M}</code> has three parts <ul> <li><code>(?=(.))\1{N}</code> captures <code>\1</code> in a lookahead, and then match it <code>N</code> times <ul> <li>Using lookahead to capture means the repetition can be <code>N</code> instead of <code>N-1</code></li> </ul></li> <li><code>.*?</code> allows an infix to separate the two runs, reluctant to keep it as short as possible</li> <li><code>(?=(?!\1)(.))\2{M}</code> <ul> <li>Similar to first part</li> <li>Nested negative lookahead ensures that <code>\1</code> != <code>\2</code></li> </ul></li> </ul></li> </ul> <p>The run regex will match longer runs, e.g. <code>run(2,2)</code> matches <code>"xxxyyy"</code>:</p> <pre><code>xxxyyy &lt;- (?=(.))\1{2}.*?(?=(?!\1)(.))\2{2} match 0: [xxxyy] 1: [x] 2: [y] </code></pre> <p>Also, it does not allow overlapping matches. That is, there is only one <code>run(2,3)</code> in <code>"xx11yyy222"</code>.</p> <pre><code>xx11yyy222 &lt;- (?=(.))\1{2}.*?(?=(?!\1)(.))\2{3} match 0: [xx11yyy] 1: [x] 2: [y] </code></pre>
    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.
    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