在字符前后有条件的匹配字符串

3
正则表达式总是让我头疼。我正在尝试匹配一个模式,只有在前后两个字符都不是数字的情况下才能匹配成功,如果其中一个字符是数字也可以。例如 "Zeitraum vom 1. 6. -30. 6.",我想匹配破折号 (-),但对于 "12-3-2019"(破折号前后的字符都是数字)则不应匹配成功。目前我正在尝试排除法,但这似乎只适用于前后都不是数字的情况。
[^\d]-[^\d]

谢谢您

2个回答

3

您可以使用

r'-(?<!\d-(?=\d))'

请查看正则表达式演示
它匹配不是数字的连字符-和紧接着数字的连字符-。
请注意,必须使用前瞻(?=\d),而不能使用简单的\d,因为在连字符-之后使用否定回顾(?<!\d-\d)时,当回溯时会导致匹配失败。 详细信息
  • - - 连字符
  • (?<! - 负向回顾开始:如果当前位置左侧紧邻处有
    • \d - 数字
    • - - 连字符
    • (?=\d) - 接下来是\d
  • ) - 回顾结束

1
太棒了,你们真是太厉害了。@Wiktor,我会接受Totos的答案,因为他回答得很快,而且我觉得他的解决方案稍微容易阅读一些。 - Fabian Bosler
1
@FabianBosler 我的回答是第一个,但你可以随意选择。 - Wiktor Stribiżew
@Cid 可读性优先于性能 - 抱歉,我属于另一个“正则表达式学派”。当涉及到正则表达式时,我总是更喜欢性能。 - Wiktor Stribiżew
2
@Cid 你需要了解一下“回到未来的后顾向断言”。那个“-”必须要消耗掉连字符,这样后顾向模式才能停止继续消耗并回溯到我们不想要的地方。你可以把它看作是一个“锚点”。 - Wiktor Stribiżew
@WiktorStribiżew 现在我明白了,我想我错过了在字符串中的 当前位置。那个网站是很不错的阅读材料,我会收藏的。 - Cid
显示剩余4条评论

3

您可以使用替代:

(?<!\d)-|-(?!\d)

这个匹配与连字符不紧跟在数字前面或不紧跟在数字后面相对应。


太棒了!这好像可以工作,您能解释一下它是做什么的吗?:D - Fabian Bosler
@FabianBosler:(?<!..) 构造是负向先行断言,它是一个零长度的断言,确保当前位置之前没有数字。请参见:https://www.regular-expressions.info/lookaround.html - Toto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接