Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <pre><code>private static String combineRE(String p1, String p2){ int groups1 = 0, groups2=0; StringBuilder newP = new StringBuilder("(?="); newP.append(p1); newP.append("$)(?="); Pattern capturingGroup = Pattern.compile("(?&lt;!\\\\)(\\\\\\\\)*\\((?!\\?)"); Matcher m = capturingGroup.matcher(p1); while(m.find()) groups1 ++; m = capturingGroup.matcher(p2); while(m.find()) groups2 ++; String new2 = p2; for(int i=1; i&lt;=groups2; i++) new2 = new2.replaceAll("(?&lt;!\\\\)\\\\"+i, "\\\\" + (i+groups1)); newP.append(new2); newP.append("$).*"); return newP.toString(); } </code></pre> <p>This function uses the basic structure <code>(?=p1$)(?=p2$).*</code>, while recounting the numbered backreferences int the second pattern. It uses a regular expression to count the number of capturing group openers (unescaped <code>(</code>s not followed by a <code>?</code>) in each pattern, then updates the backrefences in the second pattern before placing it in the resultant pattern. I've set up a testing environment with ideone: Please, add all the test cases you can think of, but I think this answers your question.</p> <p><a href="http://ideone.com/Wm8cRc" rel="nofollow">http://ideone.com/Wm8cRc</a></p> <p>Round 2:</p> <p>There's no good way to generate a Pattern that will <code>find()</code> a substring to match two patterns. I toyed briefly with <code>(?=p1(?&lt;p2)).*(?&lt;(?=p1)p2)</code> and other such nonsense before giving up and writing, instead, an algorithm. First, I slightly modified my CombineRE from before:</p> <pre><code>private static String combineRE(String p1, String p2, boolean anchors){ int groups1 = 0, groups2=0; StringBuilder newP = new StringBuilder((anchors)?"^(?=":"(?="); newP.append(p1); if (anchors) newP.append('$'); newP.append(")(?="); Pattern capturingGroup = Pattern.compile("(?&lt;!\\\\)(\\\\\\\\)*\\((?!\\?)"); Matcher m = capturingGroup.matcher(p1); while(m.find()) groups1 ++; m = capturingGroup.matcher(p2); while(m.find()) groups2 ++; String new2 = p2; for(int i=1; i&lt;=groups2; i++) new2 = new2.replaceAll("(?&lt;!\\\\)\\\\"+i, "\\\\" + (i+groups1)); newP.append(new2); if (anchors) newP.append('$'); newP.append(')'); if (anchors) newP.append(".*"); return newP.toString(); } </code></pre> <p>You'll see that it now supports optional anchors. I used this functionality in my new function:</p> <pre><code>private static String[] findAllCombinedRE(String p1, String p2, String haystack, boolean overlap){ ArrayList&lt;String&gt; toReturn = new ArrayList&lt;String&gt;(); Pattern pCombo = Pattern.compile(combineRE(p1,p2, false)); String pComboMatch = combineRE(p1,p2, true); Matcher m = pCombo.matcher(haystack); int s = 0; while (m.find(s)){ String match = haystack.substring(m.start()); s = m.start()+1; for (int i=match.length(); i&gt;0; i--){ String sMatch = match.substring(0,i); if (Pattern.matches(pComboMatch, sMatch)){ toReturn.add(sMatch); /** * Note that at this point we can caluclute match * object like Information: * * group() = sMatch; * start() = m.start(); * end() = m.start() + i; * * If it so suited us, we could pass this information * back in a wrapped object. */ if (!overlap){ s = m.start()+i; break; } } } } return toReturn.toArray(new String[]{}); } </code></pre> <p>It uses an anchor free version of the two Regular Expressions to find all strings that might match, then chops off one letter at a time until the string matches the anchored version. It also includes a boolean to control for overlapping matches.</p> <p><a href="http://ideone.com/CBoBN5" rel="nofollow">http://ideone.com/CBoBN5</a> Works pretty well.</p>
    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. This table or related slice is empty.
    1. 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