【问题标题】:Non-greedy Pattern Expression非贪婪模式表达式
【发布时间】:2011-10-23 22:17:23
【问题描述】:

我一直在阅读 Friedl 的“掌握正则表达式”,并尝试为由单词分隔的字符串设计一个常见的非贪婪模式表达式。 从分隔词只是单个字符 'a' 的基础开始,表达式:

sed -r 's/([^a]*)(a)/\                                                                  
(1)\1(2)\2(ALL)&(END)/g' <<<"xaxxaxxxaxxx...aa..."

(1)x(2)a(ALL)xa(END)
(1)xx(2)a(ALL)xxa(END)
(1)xxx(2)a(ALL)xxxa(END)
(1)xxx...(2)a(ALL)xxx...a(END)
(1)(2)a(ALL)a(END)...

模式(参考 Friedl)可能来自:

  • [正常*关闭]

继续使用真正的多字符“ab”分隔符:

sed -r 's/([^a]*)((a[^b]*)*)(ab)/\                          
(1)\1(2)\2(3)\3(4)\4(ALL)&(END)/g' <<<"xabxxabxxxabxxx...abxxx...aabxxx...axxx...aaabxaabaxabaxaxabxaxaabxxaaabaaxxab..."

(1)x(2)(3)(4)ab(ALL)xab(END)
(1)xx(2)(3)(4)ab(ALL)xxab(END)
(1)xxx(2)(3)(4)ab(ALL)xxxab(END)
(1)xxx...(2)(3)(4)ab(ALL)xxx...ab(END)
(1)xxx...(2)a(3)a(4)ab(ALL)xxx...aab(END)
(1)xxx...(2)axxx...aa(3)axxx...aa(4)ab(ALL)xxx...axxx...aaab(END)
(1)x(2)a(3)a(4)ab(ALL)xaab(END)
(1)(2)ax(3)ax(4)ab(ALL)axab(END)
(1)(2)axax(3)axax(4)ab(ALL)axaxab(END)
(1)x(2)axa(3)axa(4)ab(ALL)xaxaab(END)
(1)xx(2)aa(3)aa(4)ab(ALL)xxaaab(END)
(1)(2)aaxx(3)aaxx(4)ab(ALL)aaxxab(END)...

模式可能来自于:

  • [正常*(特殊*)*关闭]

对于后续的 'abc' 定界符,special 表达式可以扩展为:

(a[^b]*)*(ab[^c]*)*
  1. 这是正确的吗?
  2. 能证明吗?
  3. special表达式可以简化吗?
  4. 是否有更好/更有效的表达方式?注意我没有使用 perl 的非贪婪 '*?'运算符并避免交替。
  5. 我在哪里可以找到此类问题的参考资料(Friedl 提到但没有公布解决方案)。

【问题讨论】:

  • 我离“掌握正则表达式”还差得很远,这甚至都不好笑。不过我很感兴趣。您是否愿意解释为什么您不想使用这两个运算符:?和|。欣赏它。
  • 为什么不使用负前瞻?
  • @Ikuty 恐怕这不是 sed 报告的一部分。
  • @potong 你说得对,我忘了考虑上下文。
  • @potong 是时候投入赏金了。 :)

标签: regex sed


【解决方案1】:
  1. 是的,看起来是正确的。
  2. 您想了解有限自动机 — 非确定性 (NFA) 和确定性 (DFA)。简单的正则表达式系统本质上是有限自动机的方便表示法。任何关于编译器的好书都会有一章涵盖 NFA 和 DFA。
  3. 可能不会,或者不多。你的词越长,你要允许的回溯就越多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 2010-10-20
    • 2013-02-15
    • 1970-01-01
    相关资源
    最近更新 更多