我进行了搜索,但找不到合适的解决方案。我正在为Excel文件的标题格式设置正则表达式。这些使用& -commands用于格式化页眉和页脚,然后左,中,右标题简单地连接在一起:
(ECMA规范中的¶18.3.1.39)
&L&"Lucida Grande,Standard"&K000000Left top&C&"Lucida Grande,Standard"&K000000Middle top&R&"Lucida Grande,Standard"&K000000Right top
所有三个部分都是可选的。根据我读到的关于使组可选的内容,我提出了以下正则表达式(Python风格):
re.compile(r"""
(?P<left>&L.+?)
(?P<center>&C.+?)
(?P<right>&R.+?)$
""", re.VERBOSE)
但它失败的是一个只包含一部分&Ltest header
的简单字符串。我想我理解了潜在的问题 - 缺少可选组的模式会影响其他模式 - 但不会影响语法,或者更确切地说,当缺少可选组时会发生什么。
答案 0 :(得分:1)
尝试
^(?:.*?(?P<left>&L.[^&]*))?(?:.*?(?P<center>&C.[^&]*))?(?:.*?(?P<right>&R.[^&]*))?.*$
left
群组的解释(center
和right
几乎相同):
(?:
.*? # consume any preceding text
(?P<left> # then capture...
&L # "&L" literally
. # the character after that
[^&]* # and then everything up to the next "&" character
)
)? # and make the whole thing optional.
P.S。:您的模式没有任何组可选。您应该在小组之后放置?
,例如(?P<left>&L.+)?
。
由于这些组不应该以下一个&
字符结束,您可以尝试使用该模式
(?P<left>&L.+?)?(?P<center>&C.+?)?(?P<right>&R.+?)?$
代替。我所做的就是通过添加?
使所有组成为可选组,并通过将锚$
放在最后来强制模式使用整个字符串。
更新:(?:&L(?P<left>.+?))?(?:&C(?P<center>.+?))?(?:&R(?P<right>.+?))?$
无法捕获&L
,&C
和&R
位。
答案 1 :(得分:1)
您可以使用与left/center/right
匹配的正则表达式以及一系列替换
条件用于匹配部件,而不管它们在行中出现的顺序
这样就可以匹配1,2或3个。
已更新
修改以匹配每个部分直到下一部分(如果它在那里) 基于此处有关条件的信息 - &gt; http://www.rexegg.com/regex-conditionals.html
如果它的python / PCRE应该可以工作:
(?:(?:[^&]|&[\S\s])*?(?:&L(?P<left>(?(left)(?!))(?:[^&]|&[^LCR])*)|&C(?P<center>(?(center)(?!))(?:[^&]|&[^LCR])*)|&R(?P<right>(?(right)(?!))(?:[^&]|&[^LCR])*))){1,3}
如果是Perl / PCRE,这可行:
# (?:(?:[^&]|&[\S\s])*?(?:&L(?<left>(?(<left>)(?!))(?:[^&]|&[^LCR])*)|&C(?<center>(?(<center>)(?!))(?:[^&]|&[^LCR])*)|&R(?<right>(?(<right>)(?!))(?:[^&]|&[^LCR])*))){1,3}
(?:
(?: [^&] | & [\S\s] )*? # Get all possible quoted &&
# even &[LCR] if needed
(?: # Get one of &L or &C or &R
&L
(?<left> # (1), Left
(?(<left>)
(?!) # Allow only 1 left
)
(?: [^&] | & [^LCR] )* # Get all possible quoted && up to but not &[LCR]
)
|
&C
(?<center> # (2), Center
(?(<center>)
(?!) # Allow only 1 center
)
(?: [^&] | & [^LCR] )*
)
|
&R
(?<right> # (3), Right
(?(<right>)
(?!) # Allow only 1 right
)
(?: [^&] | & [^LCR] )*
)
)
){1,3} # Do 1 to 3 times
输出:
** Grp 0 - ( pos 0 , len 132 )
&L&"Lucida Grande,Standard"&K000000Left top&C&"Lucida Grande,Standard"&K000000Middle top&R&"Lucida Grande,Standard"&K000000Right top
** Grp 1 - ( pos 2 , len 41 )
&"Lucida Grande,Standard"&K000000Left top
** Grp 2 - ( pos 45 , len 43 )
&"Lucida Grande,Standard"&K000000Middle top
** Grp 3 - ( pos 90 , len 42 )
&"Lucida Grande,Standard"&K000000Right top