正则表达式 - 将字符串匹配到另一个字符串,可选

时间:2015-11-18 11:32:19

标签: php regex

我试图在PHP中解析可能(或可能不)落在起始端标记之间的消息,如下所示:

Some rubbish
------- start message -------
Here's the actual message
------- end message ---------
more rubbish

我尝试这个表达方式:

/^(?:(?:.*)?\n-{3,} ?begin message ?-{3,})?(.*)(?:\n-{3,} ?end message ?-{3,})?/is

然而似乎(。*)也捕获来自" Here"的所有文本。到字符串的末尾。如果我将结束标记的匹配设置为非条件,则捕获正常,但如果结束标记不在那里则不匹配。

如果我给(。*)一个限制性更强的字符类([a-zA-Z - \ s] *),它确实有用,但我不想这么严格。

我需要前瞻性的东西吗?

2 个答案:

答案 0 :(得分:1)

您可以使用它来匹配以-{7} start message -{7}开头,最多------- end message -------的所有内容:

-{7} start message -{7}([^-]*(?:-(?!-{6} end message -{7})[^-]*)*)

请参阅regex demo

正则表达式基于unrolling-the-loop method

正则表达式分解:

  • -{7} start message -{7} - 正好匹配7个连字符,空格start message,空格和7个连字符。
  • ([^-]*(?:-(?!-{6} end message -{7})[^-]*)*) - 捕获第1组匹配...
    • [^-]* - 除-
    • 以外的0个或多个字符
    • (?:-(?!-{6} end message -{7})[^-]*)* - 0个或更多个序列...
      • -(?!-{6} end message -{7}) - 一个连字符,后面跟着6个连字符,空格,end message,空格和7个连字符
      • [^-]* - 除连字符以外的0个或多个字符。
  

开始标记也需要是可选的

好吧,你真的可以省略-{7} start message -{7},或者把它放到一个可选组中:

(?:-{7} start message -{7})?([^-]*(?:-(?!-{6} end message -{7})[^-]*)*)
^^^ ------ optional -------^

请注意,如果您省略它,模式也将匹配空字符串。

答案 1 :(得分:0)

试试这个:

start\s+?message\s+?-------\r?\n([\d\D]+?)-------\s+?end\s+?message

如果您想知道我使用[\d\D]代替.的原因:

在许多环境中,.不包含\n字符,一旦找到正则表达式就会停止,你可以使用m修饰符绕过它,但它并不总是工作。 [\d\D]包含\n,您可以使用任意对应的字符组,它们都是相同的:[\s\S][\w\W] ...