WeizhongTu
WeizhongTu

Reputation: 6414

python regex replace only part of NOT match

I have many html codes which have <pre> python code </pre>, just like following

html code:

<pre class="c1">
# regex usage
import re
re.findall(r'abc','abcde')
</pre>

python tutorial ...python regex<br>

<pre class="c2">
# regex usage
import re
re.findall(r'abc','abcde')
</pre>

I regard regex as a keyword, and replace it to a link: <a href="link-to-regex">regex</a>,but I don't want to replace contents in label <pre>

output:

<pre class="c1">
# regex usage
import re
re.findall(r'abc','abcde')
</pre>

python tutorial ...python <a href="link-to-regex">regex</a><br>

<pre class="c2">
# regex usage
import re
re.findall(r'abc','abcde')
</pre>

I do it use placeholders

pre_list = re.compile(r'(<pre>.+?</pre>)').findall(html_code)

# use CODE_PLACEHODER to protect code sources
for index,code in enumerate(pre_list):
    html_code = html_code.replace(code, 'CODE_PLACEHOLDER_{}'.format(index))

# replace the html content here
html_code = html_code.replace('regex', '<a href="link-to-regex">regex</a>')

for index,code in enumerate(pre_list):
    html_code = html_code.replace('CODE_PLACEHOLDER_{}'.format(index), code)
    enter code here

Better method to do this?

Upvotes: 0

Views: 121

Answers (2)

Avinash Raj
Avinash Raj

Reputation: 174696

Use positive lookaround assertions to match the string regex which is not present inside the <pre> tag. And don't forget to enable DOTALL modifier.

>>> import re
>>> s = """<pre>
# regex usage
import re
re.findall(r'abc','abcde')
</pre>

python tutorial ...python regex<br>
<pre>
# regex usage
import re
re.findall(r'abc','abcde')
</pre>"""
>>> m = re.sub(r'(?s)regex(?!(?:(?!<\/?pre[^<>]*>).)*<\/pre>)', r'<a href="link-to-regex">regex</a>', s)
>>> print m
<pre>
# regex usage
import re
re.findall(r'abc','abcde')
</pre>

python tutorial ...python <a href="link-to-regex">regex</a><br>
<pre>
# regex usage
import re
re.findall(r'abc','abcde')
</pre>

DEMO

Upvotes: 1

vks
vks

Reputation: 67968

regex(?=(?:((?!<pre[^>]*>|<\/pre>).)*<pre[^>]*>(?:(?!<\/pre>).)*<\/pre>)*(?:(?!<pre[^>]*>|<\/pre>).)*$)

Try this.See demo.

http://regex101.com/r/rQ6mK9/8

Upvotes: 0

Related Questions