PHP/PCRE 正则表达式以递归模式开头
PHP/PCRE regex starts with on recursive pattern
我正在尝试将降价标签与递归相匹配。
输入语法
(TYPE: VALUE ATTR_KEY: ATTR_VALUE)
请注意,语法应以:[a-z0-9_-]+:
开头
示例输入:
(image: sky.jpg)
(image: sky.jpg caption: Sky (Issue This) View)
(link: https://whosebug.com text: Stack Overflow)
(link: https://whosebug.com text: Stack Overflow rel=nofollow)
(video: http://www.youtube.com/watch?v=49Kh1mS4Fhs)
当前使用以下正则表达式:
(?=[^\]])\([a-z0-9_-]+:.*?\)
但问题来自这里,因为匹配:
(image: sky.jpg caption: Sky (Issue This)
预期匹配:
(image: sky.jpg caption: Sky (Issue This) View)
如果括号中再次使用括号,则不完全匹配。
我试过遵循递归模式并且有效,但我需要限制以字符开头。
(?s)\((?:[^()]+|(?R))*+\)
\((?:[^)(]+|(?R))*+\)
您应该使用积极的前瞻来匹配确保匹配以该模式开始,但是您必须将整个括号匹配模式包装在另一个捕获组中并使用 (?1)
subroutine 而不是 (?R)
只递归那个模式,而不是整个正则表达式:
(?=\([a-z0-9_-]+:)(\((?:[^()]+|(?1))*+\))
^^^^^^^^^^^^^^^^^^^ ^^^^ ^
参见regex demo。
详情
(?=\([a-z0-9_-]+:)
- 正向前瞻,需要 (
、1+ 个小写 ASCII 字母、数字、下划线或连字符后跟 :
,紧接在当前位置
(\((?:[^()]+|(?1))*+\))
- 捕获第1组(稍后会递归):
\(
- (
(?:[^()]+|(?1))*+
- 1+ 重复 1+ 除 (
和 )
以外的任何字符或整个第 1 组模式(递归)
\)
- )
如果您还想支持笑脸,您可以在正则表达式子例程所在的交替组中添加它们的特定模式,作为第一个选择:
(?=\([a-z0-9_-]+:)(\((?::[)(]|[^()]|(?1))*+\))
^^^^^
我添加 :[)(]
匹配 :)
或 :(
并从 [^()]
之后删除 +
以便能够检查嵌套内的字符串括号逐个字符。
随时根据您的需要进行调整,或添加 。
使用 (?=\([a-z0-9_-]+:)(\((?::(?:[()pPDd*oO]|'\()|<3|;\)|[^()]|(?1))*+\))
正则表达式参见 this regex demo。
我正在尝试将降价标签与递归相匹配。
输入语法
(TYPE: VALUE ATTR_KEY: ATTR_VALUE)
请注意,语法应以:[a-z0-9_-]+:
示例输入:
(image: sky.jpg)
(image: sky.jpg caption: Sky (Issue This) View)
(link: https://whosebug.com text: Stack Overflow)
(link: https://whosebug.com text: Stack Overflow rel=nofollow)
(video: http://www.youtube.com/watch?v=49Kh1mS4Fhs)
当前使用以下正则表达式:
(?=[^\]])\([a-z0-9_-]+:.*?\)
但问题来自这里,因为匹配:
(image: sky.jpg caption: Sky (Issue This)
预期匹配:
(image: sky.jpg caption: Sky (Issue This) View)
如果括号中再次使用括号,则不完全匹配。
我试过遵循递归模式并且有效,但我需要限制以字符开头。
(?s)\((?:[^()]+|(?R))*+\)
\((?:[^)(]+|(?R))*+\)
您应该使用积极的前瞻来匹配确保匹配以该模式开始,但是您必须将整个括号匹配模式包装在另一个捕获组中并使用 (?1)
subroutine 而不是 (?R)
只递归那个模式,而不是整个正则表达式:
(?=\([a-z0-9_-]+:)(\((?:[^()]+|(?1))*+\))
^^^^^^^^^^^^^^^^^^^ ^^^^ ^
参见regex demo。
详情
(?=\([a-z0-9_-]+:)
- 正向前瞻,需要(
、1+ 个小写 ASCII 字母、数字、下划线或连字符后跟:
,紧接在当前位置(\((?:[^()]+|(?1))*+\))
- 捕获第1组(稍后会递归):\(
-(
(?:[^()]+|(?1))*+
- 1+ 重复 1+ 除(
和)
以外的任何字符或整个第 1 组模式(递归)\)
-)
如果您还想支持笑脸,您可以在正则表达式子例程所在的交替组中添加它们的特定模式,作为第一个选择:
(?=\([a-z0-9_-]+:)(\((?::[)(]|[^()]|(?1))*+\))
^^^^^
我添加 :[)(]
匹配 :)
或 :(
并从 [^()]
之后删除 +
以便能够检查嵌套内的字符串括号逐个字符。
随时根据您的需要进行调整,或添加
使用 (?=\([a-z0-9_-]+:)(\((?::(?:[()pPDd*oO]|'\()|<3|;\)|[^()]|(?1))*+\))
正则表达式参见 this regex demo。