我试图在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] *),它确实有用,但我不想这么严格。
我需要前瞻性的东西吗?
答案 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组匹配...
[^-]*
- 除-
(?:-(?!-{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]
...