我有一个存储在变量中的字符串$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? ';
我想删除字符串中没有结尾的所有行.
,?
或者!
.我该如何有效地做到这一点?也许是一种preg_replace()
方法?
如果行末尾没有空格,则可以使用
'~^.*(?请参阅正则表达式演示
说明:
^
-线路的开始(如/m
改性剂表示多行模式时^
和$
匹配的开始和结束行,而不是字符串)
.*
- 任何字符,但换行符...
(?- 字符串的末尾,前面带有
.
或!
或?
\R?
- 可选的换行符
要忽略尾随空格,请使用基于前瞻的正则表达式:
'~^(?!.*[.?!]\h*$).*$\R?~m'请参阅正则表达式演示
说明:
^
- 开始一条线
(?!.*[.?!]\h*$)
- 如果有一个匹配或者在字符串的末尾后跟可选的水平空格().
,则表示匹配失败?
!
\h*
.*$
- 任何字符,但换行符,0或更多次出现,直到行尾
\R?
- 可选的换行序列(可选,因为最后一行可能没有后跟换行符).
PHP代码演示:
$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]
在前瞻中添加一个字符类:^(?!.*[.?!][\p{P}\h]*$).*$\R?见演示.现在,前瞻看起来像
(?!.*[.?!][\p{P}\h]*$)
.如果有a.
,?
或!
后跟标点符号(\p{P}
)或水平空格(\h
),零次或多次出现(*
),则匹配失败.AND FINAL UPDATE:如果你还需要忽略所有非单词符号(包括Unicode字母)和所有HTML实体,你可以使用
'~^(?!.*[.?!](&\w+;|\W)*$).*$\R?~m'查看另一个正则表达式演示和IDEONE演示.该行结尾
. Â
并. ÂÂ
没有得到清除.这里的区别
(&\w+;|\W)*
在于匹配0个或更多个子串,&
以1个或多个单词字符(字母[A-Za-z]
,数字([0-9]
)或下划线开头和后跟),然后是分号或非单词字符(\W
).您可以展开模式,[^\w&]*(?:&\w+;\W*)*
以便可以提高正则表达式的性能.请注意,您可以使用
\W
匹配除ASCII之外的所有Unicode字母和符号,因为/u
此处未使用修饰符.
如果你在regex101.com上测试,不要忘记使用`/ g`全局修饰符.见[本演示](https://regex101.com/r/gH8aS5/4).