Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:匹配之间的连续行,类似于awk 鉴于: 多行字符串字符串(已从文件中读取) 两个模式pattern1和pattern2,它们将匹配字符串中恰好一行的子字符串。这些线将被称为line1和line2_Python_Regex_String_Awk_Regex Lookarounds - Fatal编程技术网

Python:匹配之间的连续行,类似于awk 鉴于: 多行字符串字符串(已从文件中读取) 两个模式pattern1和pattern2,它们将匹配字符串中恰好一行的子字符串。这些线将被称为line1和line2

Python:匹配之间的连续行,类似于awk 鉴于: 多行字符串字符串(已从文件中读取) 两个模式pattern1和pattern2,它们将匹配字符串中恰好一行的子字符串。这些线将被称为line1和line2,python,regex,string,awk,regex-lookarounds,Python,Regex,String,Awk,Regex Lookarounds,这些模式是正则表达式模式,但是如果这样做更容易的话,我可以更改它们的格式 搜索 我正在寻找一种方法来获取python中第1行和第2行之间的所有行(我们可以安全地假设第1行在第2行之前) 当然,这可以在for循环中完成,使用由pattern1设置的标志,并在pattern2匹配时中断。不过,我在这里寻找一个更紧凑的解决方案。这是awk中的一个简单的单行程序: awk '/pattern1/,/pattern2/' file 例子: 文件: 模式1:bb 模式2:dd 预期结果: bbb bb b

这些模式是正则表达式模式,但是如果这样做更容易的话,我可以更改它们的格式

搜索 我正在寻找一种方法来获取python中第1行和第2行之间的所有行(我们可以安全地假设第1行在第2行之前)

当然,这可以在for循环中完成,使用由
pattern1
设置的标志,并在
pattern2
匹配时中断。不过,我在这里寻找一个更紧凑的解决方案。这是
awk
中的一个简单的单行程序:

awk '/pattern1/,/pattern2/' file
例子: 文件:

模式1:
bb

模式2:
dd

预期结果:

bbb bb b
ccc cc c
ddd dd d

使用
regex

>>> print(a)

aaa aa a
bbb bb b
ccc cc c
ddd dd d
eee ee e
fff ff f
预期结果:

>>> print(re.search('^.*bb b$\n((:?.+\n)+)^.*dd d$',a, re.M).group())
bbb bb b
ccc cc c
ddd dd d
或仅随附文本:

>>> print(re.search('^.*bb b$\n((:?.+\n)+)^.*dd d$',a, re.M).group(1))
ccc cc c

使用re.DOTALL匹配任何内容,包括换行符。然后插入开始模式和结束模式:

re.search( '[\w ]*b bb.*?d dd[ \w]*', string, re.DOTALL).group(0)
re.search( '[\w ]*b bb.*?d dd[ \w]*', open('file').read(), re.DOTALL).group(0) 
注意:(1)
string
这是您要搜索的文件或字符串。(2) 您需要
导入re
。如果您真的希望简洁,可能会有问题,您可以将读取文件和提取模式结合起来:

re.search( '[\w ]*b bb.*?d dd[ \w]*', string, re.DOTALL).group(0)
re.search( '[\w ]*b bb.*?d dd[ \w]*', open('file').read(), re.DOTALL).group(0) 

awk
中,
/start/,/end/
范围正则表达式打印
/start/
所在的整行,包括找到
/end/
模式的整行。它是一个有用的构造,已被Perl、sed、Ruby和其他人复制

要在Python中执行范围运算符,请编写一个类,该类跟踪上一次调用
start
运算符直到
end
运算符的状态。我们可以使用正则表达式(正如
awk
所做的那样),也可以简单地修改为任何返回
True
False
状态的数据行

根据示例文件,您可以执行以下操作:

import re

class FlipFlop: 
    ''' Class to imitate the bahavior of /start/, /end/ flip flop in awk '''
    def __init__(self, start_pattern, end_pattern):
        self.patterns = start_pattern, end_pattern
        self.state = False
    def __call__(self, st):
        ms=[e.search(st) for e in self.patterns]
        if all(m for m in ms):
            self.state = False
            return True
        rtr=True if self.state else False
        if ms[self.state]:
            self.state = not self.state
        return self.state or rtr

with open('/tmp/file') as f:
    ff=FlipFlop(re.compile('b bb'), re.compile('d dd'))
    print ''.join(line if ff(line) else "" for line in f)
印刷品:

bbb bb b
ccc cc c
ddd dd d
它保留了一行一行的文件读取,具有其他语言中所见的
/start/,/end/
regex的灵活性。当然,您可以对多行字符串(假定名称为
s
)执行相同的方法:

习惯上,在awk中,使用标志可以获得与触发器相同的结果:

$ awk '/b bb/{flag=1} flag{print $0} /d dd/{flag=0}' file
您也可以在Python中复制它(使用更多的单词):

也可以与内存中的字符串一起使用

或者,您可以使用多行正则表达式:

with open('/tmp/file') as f:
    print ''.join(re.findall(r'^.*b bb[\s\S]*d dd.*$', f.read(), re.M))

但这需要将整个文件读入内存。由于您声明字符串已读入内存,因此在这种情况下,这可能是最简单的:

''.join(re.findall(r'^.*b bb[\s\S]*d dd.*$', s, re.M))

我想用python来做。(更正)有任何反馈吗?不捕获
pattern1
之前的行,也不捕获
pattern2
之后的行的剩余部分。啊,OP更改了他想要的内容。编辑以适应。谢谢。这还不包括带
bb
的行的开头或带
dd
的行的结尾。整行需要从头到尾打印。现在它只匹配第2-n-1行。不要使用
\n
使用
re.M
,然后将
^
$
添加到您的模式中。@dawg,我认为数据匹配正确,不是吗?而且,使用re.M意味着我必须在模式中包含换行符。正则表达式
^.+bb b$\n((:?。++\n)+^.+dd d$
至少需要在
bb b
之前加一个字符,在
dd d
之前加一个字符,因为
+
vs
.
''.join(re.findall(r'^.*b bb[\s\S]*d dd.*$', s, re.M))