Regex匹配某些标记之外的所有新行字符


Regex to match all new line characters outside of some tag

我需要匹配特定html标记或伪标记以外的所有新行字符。

下面是一个例子。我想在此文本片段中匹配[code] [/code]标签之外的所有"'n" s(以便用<br>标签替换它们):

These concepts are represented by simple Python classes.  
Edit the polls/models.py file so it looks like this: 
[code]  
from django.db import models
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published') 
[/code]

我知道我应该使用负面的正面,但我正在努力弄清楚整件事。

具体来说,我需要一个PCRE表达式,我将使用它与PHP,也许Python。

对我来说,这种情况似乎直接脱离了匹配(或替换)模式,除了情况s1, s2, s3等。请访问该链接以获得解决方案的完整讨论。

我将给你PHP和Python的答案(因为这个例子提到了django)。

PHP

(?s)'[code'].*?'[/code'](*SKIP)(*F)|'n

左侧的选项匹配complete [code]…[/code]标记,然后故意失败,并跳过刚刚匹配的字符串部分。右边匹配换行符,我们知道它们是右换行符,因为它们没有被左边的表达式匹配。

这个PHP程序展示了如何使用正则表达式(参见在线演示底部的结果):

<?php
$regex = '~(?s)'[code'].*?'[/code'](*SKIP)(*F)|'n~';
$subject = "These concepts are represented by simple Python classes.
Edit the polls/models.py file so it looks like this:
[code]
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
[/code]";
$replaced = preg_replace($regex,"<br />",$subject);
echo $replaced."<br />'n";
?>
Python

对于Python,下面是我们的简单正则表达式:

(?s)'[code'].*?'[/code']|('n)

交替的左侧匹配完整的[code]...[/code]标记。我们将忽略这些匹配。右边匹配并捕获换行符到第1组,我们知道它们是正确的换行符,因为它们没有被左边的表达式匹配。

这个Python程序展示了如何使用正则表达式(参见在线演示底部的结果):

import re
subject = """These concepts are represented by simple Python classes.  
Edit the polls/models.py file so it looks like this: 
[code]  
from django.db import models
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published') 
[/code]"""
regex = re.compile(r'(?s)'[code'].*?'[/code']|('n)')
def myreplacement(m):
    if m.group(1):
        return "<br />"
    else:
        return m.group(0)
replaced = regex.sub(myreplacement, subject)
print(replaced)

这是另一个用python实现的解决方案,但不使用regex。它还可以处理嵌套的代码块(如果需要的话)并逐行读取文件,这在处理非常大的文件时非常有用。

input_file = open('file.txt', 'r')
output_file = open('output.txt', 'w')
    in_code = 0
    for line in input_file:
        if line.startswith('[code]'):
            if in_code == 0:
                line = ''n' + line
            in_code += 1
            output_file.write(line)
        elif line.startswith('[/code]'):
            in_code -= 1
            output_file.write(line)
        else:
            if in_code == 0:
                output_file.write(line.rstrip(''n') + '<br />')
            else:
                output_file.write(line)