什么是正则表达式来替换/删除 END 之前没有未结束的 START?

Posted

技术标签:

【中文标题】什么是正则表达式来替换/删除 END 之前没有未结束的 START?【英文标题】:What would be a regex to replace/remove END where its not been preceded by an unended START? 【发布时间】:2011-05-21 22:47:35 【问题描述】:

什么是正则表达式 (php) 来替换/删除(使用 preg_replace())END 之前没有未结束的 START?

这里有几个例子可以更好地描述我的意思:

示例 1:

输入:

sometext....END

输出:

sometext.... //because theres no START, therefore no need for the excess END

示例 2:

输入:

STARTsometext....END

输出:

STARTsometext....END //because its preceded by a START

示例 3:

输入:

STARTsometext....END.......END

输出:

STARTsometext....END....... //because the END is not preceded by a START

希望有人能提供帮助?

谢谢。

【问题讨论】:

如果你想要一个解析器,你需要写一个解析器。 一旦您必须识别嵌套分隔符的级别(括号、括号、开始/结束等),您可能应该考虑使用解析库,甚至滚动您自己的简单下推自动机,而不是正则表达式。即使您平台的正则表达式库支持使这成为可能的扩展,该解决方案也可能很脆弱且难以维护。 我不是在寻找一个解析器,它更像是一个小的正则表达式来修复多余的 END。我的正则表达式技能有限,因为我不确定如何检查它是否没有被 START 替换? 这不是一个可以用正则表达式匹配的模式。没有人能够为您提供一个小的正则表达式来执行此操作。这与您的技能无关。 实际上,我很确定有一个小的正则表达式可以删除那些 END s,但有一些澄清:1. 每行中有多少个开始/结束序列? 2. 可以嵌套吗? 3. Start 是否应该始终紧跟在前一个 End 之后,例如 S...ES...E...S...E.....S...E...E 【参考方案1】:

假设您不是在寻找嵌套对,有一个简单的解决方案可以去除多余的 END。考虑:

$str = preg_replace("/END|(START.*?END)/", "$1", $str);

这有点向后替换,但如果您了解引擎的工作顺序,它就很有意义。首先,正则表达式由两个主要部分组成:END|()。从左到右尝试交替,因此如果引擎在输入字符串中看到END,它将匹配它并继续进行下一个匹配(即再次查找END)。 第二部分是一个捕获组,其中包含START.*?END - 如果可能,这将匹配整个开始/结束标记。将跳过其他所有内容,直到找到另一个 END 或 START。

由于我们在替换中使用$1,即捕获的组,因此我们只保存第二个令牌。因此,END 生存的唯一方法是进入捕获组,成为START 之后的第一个。

例如,对于文本END START 123 END abc END。正则表达式将找到以下匹配项,并相应地保留、跳过或删除它们:

END - 已移除 (START 123 END) - 捕获 a - 跳过 b - 跳过 c - 跳过 END - 已删除

工作示例:http://ideone.com/suVYh

【讨论】:

使用捕获组的绝佳答案。爱它。 :)【参考方案2】:

这是非常规语言的教科书示例(START 和 END 相当于左括号和右括号)。这意味着您无法将这种语言与简单的正则表达式匹配。您可以使用复杂的正则表达式达到特定的深度,但不能任意深度。

你需要编写一个语言解析器。

相关阅读:

http://www.amazon.com/Introduction-Automata-Theory-Languages-Computation/dp/0321462254/ref=sr_1_1?ie=UTF8&qid=1291768284&sr=8-1

【讨论】:

【参考方案3】:

不可能为所有可能的语法编写正则表达式。对于您的情况,您可能需要一个上下文无关的解析器,例如上升或下降解析器。见:http://en.wikipedia.org/wiki/Formal_grammar

【讨论】:

以上是关于什么是正则表达式来替换/删除 END 之前没有未结束的 START?的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式替换但忽略最后一个字符

删除 iframe 的正则表达式

正则表达式删除字符前字符串中间的空格

PySpark 2 - 正则表达式替换 <BR> 之前的所有内容

有没有更简洁的方法来删除非字母数字字符并替换空格?

BigQuery 正则表达式从字符串中删除/替换文本列表