python find image with path in file
<p>I'd like to find svgs or pngs withing a file. The images are in a attribue v="..."</p>

<p>A part of the file looks like this:</p>

<pre><code>&lt;symbol alpha="1" type="marker" name="0"&gt;
&lt;layer pass="0" class="SvgMarker" locked="0"&gt;
&lt;prop k="angle" v="0"/&gt;
&lt;prop k="fill" v="#000000"/&gt;
&lt;prop k="name" v="../Downloads/Inkscape_vectorisation_test.svg"/&gt;
&lt;prop k="offset" v="0,0"/&gt;
&lt;prop k="offset_unit" v="MM"/&gt;
&lt;prop k="outline" v="#000000"/&gt;
&lt;prop k="outline-width" v="1"/&gt;
&lt;prop k="outline_width_unit" v="MM"/&gt;
&lt;prop k="size" v="hello.png"/&gt;
&lt;prop k="size_unit" v="MM"/&gt;
&lt;/layer&gt;
</code></pre>

<p>I'd like to get a list like:</p>

<p>['../Downloads/Inkscape_vectorisation_test.svg','hello.png']</p>

<p>My python code:</p>

<pre><code>import re
projectFile = open("project.xml", "r")
regex = re.compile(r'(?&lt;=v\=").+(\.svg|\.png)(?="/&gt;)')

for line in projectFile:
    result = regex.findall(line)            
    for filename in result:
        print filename
</code></pre>

<p>I've tested my regex with <a href="http://pythex.org/" rel="nofollow">http://pythex.org/</a> which work fine but in python console the result is just <code>.svg</code> it seems the capturing group <code>(\.svg|\.png)</code> is interpreted differently. What am I doing wrong?</p>

<p>This fails because you are using <code>regex.findall</code> and you have a group in your regex: <code>(\.svg|\.png)</code>. If you change that to non-capturing group <code>(?:\.svg|\.png)</code>, then <code>findall</code> will find the whole match.</p>

<p>See the <a href="https://docs.python.org/2/library/re.html#re.RegexObject.findall" rel="nofollow">re.findall doc</a>, which says:</p>

<blockquote>
  <p>If one or more groups are present in the pattern, return a list of
  groups; this will be a list of tuples if the pattern has more than one
  group.</p>
</blockquote>

<pre><code>&gt;&gt;&gt; line = '&lt;prop k="name" v="../Downloads/Inkscape_vectorisation_test.svg"/&gt;'
&gt;&gt;&gt;
&gt;&gt;&gt; regex = re.compile(r'(?&lt;=v\=").+(\.svg|\.png)(?="/&gt;)')
&gt;&gt;&gt; regex.findall(line)
['.svg']
&gt;&gt;&gt;
&gt;&gt;&gt; regex2 = re.compile(r'(?&lt;=v\=").+(?:\.svg|\.png)(?="/&gt;)')
&gt;&gt;&gt; regex2.findall(line)
['../Downloads/Inkscape_vectorisation_test.svg']
</code></pre>

<p>Or you could use <code>re.search</code>, which will return a Match object and give you more control:</p>

<pre><code>&gt;&gt;&gt; match = regex.search(line)
&gt;&gt;&gt;
&gt;&gt;&gt; match.group(0)
'../Downloads/Inkscape_vectorisation_test.svg'
&gt;&gt;&gt;
&gt;&gt;&gt; match.group(1)
'.svg'
</code></pre>

<p><strong>On the other hand...</strong></p>

<p>Regex is only a half-solution. If you use an XML parser instead, it will take case of text encoding, escape sequences, multiline tags, different quoting styles. So, if you want a more robust solution, don't use regexes here at all.</p>

python regex