我正在使用Qt 4.6编写一个程序,我需要从像这样的表达式中捕获所有非范围文字的出现
"SUM(A1:A3)+B1-B3+SUM(D1:D3)/COUNT(D1:D3)"
,
即B1,B3,但不是A1,A3,D1,D3。我曾尝试使用QRegExp,但它不支持负面的lookbehind断言,所以我不能排除像A3,D3这样的文字。
我的正则表达式(?<!:)([A-Z]{1,4}[1-9]\\d{0,3})(?!:)
不起作用。
我需要你的意见。感谢。
答案 0 :(得分:2)
在您的情况下,您可以使用
(?:^|[^:])\b([A-Z]{1,4}[1-9]\d{0,3})\b(?!:)
第一组匹配开头的空字符串或除冒号之外的任何字符。我还添加了字边界 \b
,以便该模式与A4a
之类的内容不匹配。
通常,编写“正面”模式更简单。例如,使用
(...)(:...)?
...
表示您的[A-Z]
模式匹配单元格引用,您可以在一次传递中匹配范围和非范围,然后在循环结果时丢弃所有范围。您可以通过检查第二个捕获组是否为空来轻松检测匹配是否为范围。
答案 1 :(得分:0)
对于需要在不支持外观的引擎上使用外观的解决方案,我发现只有一种选择:“我称之为”组合式暴力破解“,但我确信这是一个更具技术性的名称。这里有一个例子:Validate proxy URL using XML regex pattern。
但当你需要找到多个事件时它不起作用。你可能自己尝试过这样的事情:
/[^:]\b([A-Z]{1,4}[1-9]\d{0,3})\b[^:]/
(我添加了\b
以更安全。另外,请记住再次逃避反斜杠。)
如果您尝试了此操作,那么您会注意到problem:在阅读+B1-
后找到第一个匹配项;因此,由于-
已被阅读,因此无法匹配下一个单元格引用B3
,因为[^:]
没有合适的字符。
要重新描述该问题,上述正则表达式只能捕获连续的单元格引用链中的所有其他匹配项,例如对于字符串,
(A1+A2+A3+A4+A5+A6)/(B1+B2+B3+B4+B5+B6)
^^^^ ^^^^ ^^^^ ^^^^ ^^^^ ^^^^
...只有指定的部分匹配,同时显示here。
没有办法在一个正则表达式中解决这个问题。你的选择:
使用非正则表达式方法。
如果你必须出于某种原因使用正则表达式,那么你唯一的希望就是能够使用至少两个正则表达式(例如使用第一个在所有类似于引用的引用字符串周围插入空格,这样就不会有连续的单元格引用链。)
或者,在不太可能的情况下,将它们捕获到子匹配中是很好的,即可以通过.cap(1)
,.cap(2)
等进行访问,您可以执行以下操作。
/[^:]\b([A-Z]{1,4}[1-9]\d{0,3})\b[^:](?:(\b([A-Z]{1,4}[1-9]\d{0,3})\b[^:](?:(\b([A-Z]{1,4}[1-9]\d{0,3})\b[^:](?:(\b([A-Z]{1,4}[1-9]\d{0,3})\b[^:](?:(\b([A-Z]{1,4}[1-9]\d{0,3})\b[^:](?:(\b([A-Z]{1,4}[1-9]\d{0,3})\b[^:](?:(\b([A-Z]{1,4}[1-9]\d{0,3})\b[^:]))?))?))?))?))?))?/
嗯,这是不可能阅读的,所以这里是一个更易阅读的版本。假装XY
扩展为我们的单元格引用表达式\b([A-Z]{1,4}[1-9]\d{0,3})\b
。然后,以上内容与:
/[^:]XY[^:](?:(XY[^:](?:(XY[^:](?:(XY[^:](?:(XY[^:](?:(XY[^:]))?))?))?))?))?))?/
看模式?在我们进一步讨论之前,您可以看到this regex matches our example perfectly。缺点是只要定义正则表达式,就只能处理一系列连续的单元格引用。以上可以处理7,除此之外breaks。
答案 2 :(得分:0)
Qt 5.0中的QRegularExpression支持(固定长度)lookbehind断言。
https://bugreports.qt-project.org/browse/QTBUG-2371于2012年3月22日关闭。 Qt 5.0于2012年12月19日发布。