使用python 3.x计算与特定正则表达式模式匹配的行

时间:2014-07-22 01:10:10

标签: python regex python-3.x

我有一个源UTF8文件(没有BOM,Windows EOL),如下所示:

~someunicodetext_someunicodetext_someunicodetext~
some_more_unicode_text_some_more_unicode_text

~someunicodetext_someunicodetext_someunicodetext~
some_more_unicode_text_some_more_unicode_text
&&even_more_text_here

~someunicodetext_someunicodetext_someunicodetext~
some_more_unicode_text_some_more_unicode_text

~someunicodetext_someunicodetext_someunicodetext~

因此有3种类型的线(如果计算空行则为4种)。我的目标是使用python正则表达式计算每个非空类型。这绝对是使用python 3.x的基于正则表达式的解决方案,因为我想了解它是如何工作的。

我的python脚本看起来像这样:

import re, codecs
pattern = re.compile(r'some_expression_here')
count = 0
with codecs.open("some_input_file", "r", "UTF8") as inputFile:
    inputFile=inputFile.read()
    lines = re.findall(pattern, inputFile)
    for match in lines:
        count +=1
print (count)

我遇到的真正问题是实际的正则表达式 ~.*~似乎能够匹配上面示例中的1,4,8等线(如果我们从1开始计算)
&&.*与第6行匹配 但我无法弄清楚如何计算非标记线,即2,5,9号线 在Notepad ++中,这个表达式^(?!(~.*~)|(&&.*)).*或者只是这个^(?!~|&).*对我有用(尽管它不完全正确),但是我在python中复制它的所有尝试都失败了......

修改 inputFile.read()没有按照我期望的方式读取文件(hello windows EOL)。哪个可能重要,也可能不重要。它的输出如下:

~someunicodetext_someunicodetext_someunicodetext~

some_more_unicode_text_some_more_unicode_text



~someunicodetext_someunicodetext_someunicodetext~

some_more_unicode_text_some_more_unicode_text

&&even_more_text_here

4 个答案:

答案 0 :(得分:1)

    x="~someunicodetext_someunicodetext_someunicodetext~ \n   \n \nsome_more_unicode_text_some_more_unicode_text \n"
    pattern=re.compile(r"(\S+)")
    print len(pattern.findall(x))

这给出了除space之外的所有行的计数。所以空行不计算。希望这有帮助。

答案 1 :(得分:0)

您可以使用re.MULTILINE标志来尝试此模式^\w.*

re.UNICODE标志也应该用于Python 2。

这是一个完整的例子:

import re, codecs

with codecs.open("input.txt", "r", "UTF8") as inputFile:
    data = inputFile.read()
pattern = re.compile(r'^\w.*', flags=re.MULTILINE)
lines = re.findall(pattern, data)

>>> data   #  note windows line termination
'~someunicodetext_someunicodetext_someunicodetext~\r\nsome_more_unicode_text_some_more_unicode_text\r\n   \t\r\n~someunicodetext_someunicodetext_someunicodetext~\r\nsome_more_unicode_text_some_more_unicode_text\r\n&&even_more_text_here\r\n\r\n~someunicodetext_someunicodetext_someunicodetext~\r\nsome_more_unicode_text_some_more_unicode_text\r\n\r\n~someunicodetext_someunicodetext_someunicodetext~\r\n'

>>> print(lines)
['some_more_unicode_text_some_more_unicode_text\r', 'some_more_unicode_text_some_more_unicode_text\r', 'some_more_unicode_text_some_more_unicode_text\r']

>>> print(len(lines))
3

因此正则表达式匹配"未标记的"根据需要使用非空白行。

答案 2 :(得分:0)

这是答案。我仍然不确定我是否正确处理Windows EOL等等,但这似乎是有效的。 另外,我希望有人能够解释我的问题在哪里以及为什么它的工作方式有效,但是很好。

这是做什么的。我们匹配在它之前有~EOL并以另一个EOL结束的每一行。同时,我们确保排除具有2个或更多连续EOL的匹配。

因此。这仅匹配标有〜

的行正下方的行
import re, codecs

regex = re.compile(r'(?!~(\r\n){2,})~\r\n.*\r\n', re.MULTILINE)
count = 0

with codecs.open('input_file', 'r', 'UTF8') as inputFile:
    inputFile=inputFile.read()
    lines = re.findall(regex, inputFile)
    for match in lines:
        count +=1
print (count)

答案 3 :(得分:0)

&#34;未标记&#34;可以将行标识为不是并且不以~ 开头且不以&开头的行。< / p>

因此以下正则表达式将起作用:

^[^&\s].*

阅读:^ =开头匹配,[^...] =一个不在的单个字符,&\s = charchter &或空白字符(即不其中之一),.* =之后可以有任何事情发生。

(我放入\s以防万一,因为你说你遇到了换行问题。我不确定是否需要它。

此外,逐行读取文件要好得多。你得到:

import re, codecs
pattern = re.compile(r'^[^&\s].*')
with codecs.open("some_input_file", "r", "UTF8") as inputFile:
    count = sum( 1 for line in inputFile if re.search(pattern, line) )
print (count)