我目前正试图编写一个过滤器,它将转换一些简单的输入文本例如标记或纯文本到某些HTML中。这个想法是给能力最终用户可以在内容中添加一些视频。所以输入可以包含simpleMarkdown和一些标签,看起来像这样:
[video url:"https://www.youtube.com/watch?v=EkluES9Rvak" width=100% ratio='16/9'
autoplay:1 caption:"Lea Verou - Regexplained"]
我想在语法上相当软,并允许属性之间的:
或=
名称和值。就像在HTML中一样,值可以选择单引号或双引号解决空格或特殊字符的问题。这就是我开始挣扎的地方!
目前,我用PHP编写了这个正则表达式:
/(?(DEFINE)
# This sub-routine will match an attribute value with or without the quotes around it.
# If the value isn't quoted then we can't accept spaces, quotes or the closing ] tag.
(?<attr_value_with_delim>(?:(?<delimiter>["']).*?(?:k<delimiter>)|[^"'=]s]+))
)
[
s*videos+
(?=[^]]*burl[=:](?<url>g<attr_value_with_delim>)) # Mandatory URL
(?=[^]]*bwidth[=:](?<width>g<attr_value_with_delim>))? # Optional width
(?=[^]]*bratio[=:](?<ratio>g<attr_value_with_delim>))? # Optional ratio
(?=[^]]*bautoplay[=:](?<autoplay>g<attr_value_with_delim>))? # Optional autoplay
(?=[^]]*bcaption[=:](?<title>g<attr_value_with_delim>))? # Optional caption
[^]]*
]/guxs
你可以在这里测试:https://regex101.com/r/hVsav8/1
可选的属性值被捕获,所以我不需要第二次重新解析匹配的标记。
我的问题:
如何处理
]
在属性值内的问题?有没有可能在没有引号的情况下捕获值?
这不是很重要,因为我可以稍后用
trim(..., '"'')
去除它在回调中,但我想看看是否有一个模式解决方案。
子程序:
(?(DEFINE)
# Match quote-delimited values
(?<attr_value_with_delim>
'(?:\.|[^'])*'
|
"(?:\.|[^"])*"
)
# Match non-quote-delimited values
(?<attr_value_without_delim>[^'"s[]]+)
# Match both types
(?<attr_value>
g<attr_value_with_delim>
|
g<attr_value_without_delim>
)
# Match attr - value pairs in the following forms:
## attr:value
## attr=value
## attr:"value'[]=:"
## attr='value"[]=:'
## attr:"val"ue"
## attr:'val'ue'
(?<attr_with_value>
s+[a-zA-Z]+[:=]g<attr_value>
)
)
实际匹配模式:
[s* # Opening bracket followed by optional whitespaces
video # Literal 'video'
g<attr_with_value>* # 0+ attribute - value pairs
(?: #
s+ # Preceding whitespaces
url[:=] # Literal 'url' followed by either ':' or '='
(?: #
's*(?:\.|[^'s])+s*' # Single or double quote-delimited,
| # space-surrounded (optional)
"s*(?:\.|[^"s])+s*" # URL that doesn't contain whitespaces
| #
g<attr_value_without_delim> # or a non-quote-delimited value
) #
) #
g<attr_with_value>* # 0+ attribute - value pairs
s*] # Optional whitespaces followed by closing bracket
这个正则表达式匹配一个视频符号,然后可以使用合法和非邪恶的方式进一步解析。它证明了这一点,但强烈建议使用regex解析类html内容。
在regex101.com上试试。