我有一个存储在变量file_name = os.path.join(os.path.dirname(__file__), 'unsorted_fruits.tex')
with open(file_name, 'r') as f:
data = f.read()
中的字符串:
$text
我想删除字符串中不以$text = '
I should not be removed.
I should not be removed.
I should not be removed?
I should not be removed!
I should be removed
I should be removed-
I should not be removed?
';
,.
或?
结尾的所有行。我该如何有效地做到这一点?也许是!
方法?
答案 0 :(得分:6)
如果行末没有空格,您可以使用
'~^.*(?<![.?!])$\R?~m'
请参阅regex demo
解释:
^
- 行首(/m
修饰符表示^
和$
匹配行的开头和结尾时的多行模式,不是字符串).*
- 任何字符,但换行符最多...... (?<![.?!])$
- 字符串末尾没有.
或!
或?
\R?
- 可选换行符要忽略尾随空格,请使用基于前瞻的正则表达式:
'~^(?!.*[.?!]\h*$).*$\R?~m'
请参阅regex demo
解释:
^
- 开始行(?!.*[.?!]\h*$)
- 如果字符串末尾有.
,?
或!
,后跟可选的水平空格({{}},则表示匹配失败的否定前瞻{1}})\h*
- 任何字符,但换行符,0次或更多次出现,直至行尾.*$
- 可选的换行符序列(可选,因为最后一行可能没有后跟换行符)。\R?
如果您需要忽略空白和标点符号 ,只需在前瞻中添加$re = '~^(?!.*[.?!]\h*$).*$\R?~m';
$str = "I should not be removed. \nI should not be removed.\nI should not be removed?\nI should not be removed! \nI should be removed\nI should be removed-\nI should not be removed? ";
$result = preg_replace($re, "", $str);
echo $result;
字符类:
[\p{P}\h]
见demo。现在,前瞻看起来像^(?!.*[.?!][\p{P}\h]*$).*$\R?
。如果(?!.*[.?!][\p{P}\h]*$)
,.
或?
后跟标点符号(!
)或水平空格(\p{P}
),零或更多,则匹配失败发生(\h
)。
AND FINAL UPDATE:如果您还需要忽略所有非单词符号(包括Unicode字母)和所有HTML实体,您可以使用
*
请参阅another regex demo和IDEONE demo。以'~^(?!.*[.?!](&\w+;|\W)*$).*$\R?~m'
和. Â
结尾的行不会被删除。
此处的差异为. ÂÂ
,其匹配0个或更多以(&\w+;|\W)*
开头的子字符串,后跟1个或多个字符(字母&
,数字([A-Za-z]
)或一个下划线)然后是一个分号或非单词字符([0-9]
)。 您可以展开模式为[^\w&]*(?:&\w+;\W*)*
,以便提升正则表达式的性能。
注意您可以使用\W
匹配除ASCII以外的所有Unicode字母和符号,因为此处未使用\W
修饰符。