Complicated python regex
<p>I have multiple lines like this:</p>

<pre><code>EWSR1{ENST00000397938}:r.1_1364_FLI1{ENST00000429175}:r.1046_3051
EML4{ENST00000318522}:r.1_929_EML4{ENST00000318522}:r.903+188_903+220_ALK{ENST00000389048}:r.4080_6220
FUS{ENST00000254108}:r.1_(608)_FUS{ENST00000254108}:r.(819)_937_DDIT3{ENST00000547303}:r.76_872
TCF3{ENST00000262965}:r.1_1795_ins27_PBX1{ENST00000420696}:r.454_6636
EML4{ENST00000318522}:r.?_ALK{ENST00000389048}:r.?
</code></pre>

<p>I need something like this as output:</p>

<p>For the first one:</p>

<pre><code>EWSR1 ENST00000397938 1 1364
FLI1 ENST00000429175 1046 3051
</code></pre>

<p>For second one:</p>

<pre><code>EML4 ENST00000318522 1 929
EML4 ENST00000318522 903+188 903+220
ALK ENST00000389048 4080 6220
</code></pre>

<p>Third one:</p>

<pre><code>FUS ENST00000254108 1 (608)
FUS ENST00000254108 (819) 937
DDIT3 ENST00000547303 76 872
</code></pre>

<p>4th one:</p>

<pre><code>TCF3 ENST00000262965 1 1795
ins27
PBX1 ENST00000420696 454 6636
</code></pre>

<p>5th one:</p>

<pre><code>EML4 ENST00000318522 ?
ALK ENST00000389048 ?
</code></pre>

<p>I have millions of lines, so i wanted to came up with a regex for this, however i was unable. I created a conditioned regex, but i am sure there is a much more elegant and easier way. Can someone show me a simpler way?</p>

<p>My solution now:</p>

<pre><code>import re
import sys

string = sys.argv[1]
if '+?' in string or '-?' in string or not "?" in string:
    for i in re.findall('\w*?\{.*?\}:r\.[\(\)\?\+\-\d]*_[\(\)\?\+\-\d]*', string):
        if 'ins' in i:
            print(re.findall('ins[A-Za-z0-9]*', i)[0])
            i = re.sub('ins[A-Za-z0-9]*', "", i)
        print(i.lstrip('_').split('{')[0], re.findall('\{(.*?)\}', i.lstrip('_'))[0], " ".join(i.lstrip('_').split('r.')[-1].split('_')))

else:
    for i in re.findall('\w*?\{.*?\}:r\.\?', string):
        if 'ins' in i:
            print(re.findall('ins[A-Za-z0-9]*', i)[0])
            i = re.sub('ins[A-Za-z0-9]*', "", i)
        print(i.lstrip('_').split('{')[0], re.findall('\{(.*?)\}', i.lstrip('_'))[0], " ".join(i.lstrip('_').split('r.')[-1].split('_')))
</code></pre>

<p>First split on <code>(?&lt;=\d|\)|\?)_(?=[a-z])</code> and you'll end up with the <em>records</em> separated, like this:</p>

<pre><code>EWSR1{ENST00000397938}:r.1_1364
FLI1{ENST00000429175}:r.1046_3051
EML4{ENST00000318522}:r.1_929
EML4{ENST00000318522}:r.903+188_903+220
ALK{ENST00000389048}:r.4080_6220
FUS{ENST00000254108}:r.1_(608)
FUS{ENST00000254108}:r.(819)_937
DDIT3{ENST00000547303}:r.76_872
TCF3{ENST00000262965}:r.1_1795
ins27
PBX1{ENST00000420696}:r.454_6636
EML4{ENST00000318522}:r.?
ALK{ENST00000389048}:r.?
</code></pre>

<p><a href="https://regex101.com/r/cu1WSu/7" rel="nofollow">See it here at regex101</a>.</p>

<p>Then replace the result again by <code>(\{|}:r\.|_)</code>  with <code></code>, ending up like <a href="https://regex101.com/r/cu1WSu/9" rel="nofollow">here on regex101</a>.</p>

<p>This will give you</p>

<pre><code>EWSR1 ENST00000397938 1 1364
FLI1 ENST00000429175 1046 3051
EML4 ENST00000318522 1 929
EML4 ENST00000318522 903+188 903+220
ALK ENST00000389048 4080 6220
FUS ENST00000254108 1 (608)
FUS ENST00000254108 (819) 937
DDIT3 ENST00000547303 76 872
TCF3 ENST00000262965 1 1795
ins27
PBX1 ENST00000420696 454 6636
EML4 ENST00000318522 ?
ALK ENST00000389048 ?
</code></pre>

python regex python-3.x