title: Java Regex: "factor out" repeated subpatterns
body: <p>I'm using a commercial closed-source Java application that, besides everything it does, allows to filter text fields by providing a regex pattern string. I'm using that filter functionality quite extensively.</p>
  
  <p>The issue I'm having is that I often find myself repeating the same exact subpatterns in the regex. For example, here</p>
  
  <pre><code>^(
      ( # pattern foo
          foo_([^_]+)_(windows|linux|osx)
      )
      |
      ( # pattern bar
          ([^_]+)_bar_(windows|linux|osx)_foo_(windows|linux|osx)
      )
  )$
  </code></pre>
  
  <p>The <code>([^_]+)</code> and <code>(windows|linux|osx)</code> parts repeat quite often.</p>
  
  <p>That's just a made up example. The original regex is more complex, about 20 times larger and has a lot of different repeats. It becomes a bit harder to read since the repeated subpatterns only keep growing in size as well as in number, and it's troublesome that when you try to modify a repeated subpattern, you have to modify all its repeats too.</p>
  
  <p>So, I played with regex101 and came up with this</p>
  
  <pre><code>^(
      ( # a dummy option, defines some frequently used capture groups
          (?!x)x # always false, so nothing matches this and the following groups ever
          (?'name'[^_]+) # group "name"
          (?'os'windows|linux|osx) # group "os"
      )
      |
      ( # pattern foo
          foo_\g'name'_\g'os'
      )
      |
      ( # pattern bar
          \g'name'_bar_\g'os'_foo_\g'os'
      )
  )$
  </code></pre>
  
  <p><a href="https://regex101.com/r/fY1hM7/2" rel="nofollow">regex101 save</a></p>
  
  <p>Now all of the subpatterns are named and whenever I reference the name, they are replaced with the subpattern string (i.e. <code>\g'os'</code> gets replaced by <code>(windows|linux|osx)</code>). The names are a lot shorter than the corresponding subpattern, they also are clear and you have to modify a subpattern once for the modification to apply everywhere in the regex.</p>
  
  <p>The issue with this improved version is that while it's a valid PHP pcre regex, it's invalid Java regex. Comments and broken lines in the regex aside, Java doesn't support <code>\g</code>, as stated in <a href="https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html" rel="nofollow">Comparison to Perl 5</a>.</p>
  
  <p>Is there any way I can "factor out" the repeated regex patterns like that in Java Regex? Don't forget that all I can do is provide a pattern string, I have no access to the code.</p>