php正则表达式:如果行不';不要以…结束。。。拆线
我在变量php正则表达式:如果行不';不要以…结束。。。拆线,php,regex,Php,Regex,我在变量$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_r
$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()
方法?如果行尾没有空格,您可以使用
'~^.*(?<![.?!])$\R?~m'
'~^(?!.*[.?!](&\w+;|\W)*$).*$\R?~m'
看
说明:
^
-行的开头
(?!.[.?!]\h*$)
-如果存在
、?
或,则会导致匹配失败的负面前瞻在字符串末尾加上可选的水平空白(\h*
)
*$
-除换行符以外的任何字符,0次或更多次出现,直到行尾
\R?
-可选换行符序列(可选,因为最后一行后面可能没有换行符)
:
如果需要忽略空格和标点符号,只需将[\p{p}\h]
字符类添加到前瞻:
^(?!.*[.?!][\p{P}\h]*$).*$\R?
看。现在,前瞻看起来像(?!.[.?!][\p{p}\h]*$)
。如果存在、?
或,则匹配失败代码>后跟标点(\p{p}
)或水平空白(\h
),零次或多次出现(*
)
和最终更新:如果您还需要忽略所有非单词符号(包括Unicode字母)和所有HTML实体,可以使用
'~^.*(?<![.?!])$\R?~m'
'~^(?!.*[.?!](&\w+;|\W)*$).*$\R?~m'
看到了吗。以结尾的行Â代码>和。Ã
请勿移除
这里的区别是(&\w+;\w)*
,它匹配0个或多个子字符串,以&
开头,后跟1个或多个单词字符(字母[A-Za-z]
、数字([0-9]
)或下划线),然后是分号或非单词字符(\w
)。您可以展开该模式,以便提高正则表达式的性能
请注意,您可以使用\W
来匹配除ASCII以外的所有Unicode字母和符号,因为此处不使用/u
修饰符 一旦这个问题符合条件,我将以50分奖励它。它必须是正则表达式吗?将字符串拆分为行,然后删除循环中的行将是非常体面的。。。更不用说更容易阅读。这不是一个复制品。在这里,每一行都作为单独的字符串进行测试,在这里,一个多行字符串应该一次性处理。@Stribizev我发现多行要求很难不将其标记为重复。将另一个问题中给出的解决方案应用于多行字符串或处理该多行字符串中的各行是很简单的。如果我错了,请纠正我,但regex演示已删除了不应删除的行。。。?(可能是因为他们的结尾有一个空格…@Stribizev这太棒了。为了完整起见,您能否添加第二个正则表达式的preg_replace()示例(忽略空格)?@Stribizev我们在100种不同类型的文本中运行了这个正则表达式,但它以一种方式失败了多次。请参见本例中$text的结尾:--是否有必要为这些类型的实例(在我们的测试中非常常见)添加异常?正如你所看到的,它现在删除了这一行。你能精确说明新的要求吗?忽略字符串末尾的任何HTML实体?试试看。如果你在regex101.com上测试,别忘了使用/g
全局修饰符。看见