正则表达式可选部分中的捕获组
Captured group in optional part of a regular expression
我想在字符串的可选部分捕获一个组。
例如:
在字符串"firstName:Bill-lastName:Gates"中,我想捕获2组:
- 比尔
- 盖茨
我使用这个正则表达式:
firstName:(.*)-lastName:(.*)
但是当姓氏部分是可选的时,我还是想捕获第一个
组(名字)。
我使用了这个正则表达式,使姓氏部分成为可选的(在非捕获组中):
firstName:(.*)(?:-lastName:(.*))?
使用这个更新的正则表达式,生成的组是:
当 lastName 部分不存在时,例如 "firstName:Bill" 捕获的组是:
- 比尔
- /空字符串/
正确,
当 firstName 和 lastName 部分存在时:"firstName:Bill-lastName:Gates",分组不正确 :
- 比尔姓氏:盖茨
- /空/
我认为这与第一个捕获组的贪婪有关,但是当姓氏部分是可选的时,如何调整此正则表达式以使正则表达式工作?
你说的对,就是贪婪。找到第一个匹配组的分隔符。因此,如果您的名字 "never" 包含破折号,则只匹配除破折号以外的所有内容与第一个匹配组。
firstName:([^-]*)(?:-lastName:(.*))?
firstName:([^-]*)(?:-lastName:(.*))?
如果您找不到这样的分隔符,则需要采用不同的方法。即使您尝试创建第一个模式 "lazy",正则表达式引擎总是更喜欢 更大的 匹配,而不是匹配额外的可选匹配。
这是因为 lazy 匹配组将 匹配满足表达式 的第一个字符串(!重要的措辞!)
可能有一个带有 look arrounds 的选项,但您也可以使用 or 语句而不提供可选匹配项:
firstName:(.*)-lastName:(.*)|firstName:(.*)
这样,正则表达式引擎将匹配 or,但更喜欢具有 2 个匹配项的模式,因为它列在最前面。只有当那不适用时,它才会尝试单场比赛。
即使您已经接受了@dognose 的回答,我向您保证其中有带破折号的名字(您不想惹怒 Jean-Claude van Damme)。我建议你这样做:
firstName:((?:(?!-lastName:).)*)(?:-lastName:(.*))?
您可以从可视化中看到 (?:(?!-lastName:).)
表示 "if the current position is not followed by '-lastName:', capture another character"
我想在字符串的可选部分捕获一个组。
例如:
在字符串"firstName:Bill-lastName:Gates"中,我想捕获2组:
- 比尔
- 盖茨
我使用这个正则表达式:
firstName:(.*)-lastName:(.*)
但是当姓氏部分是可选的时,我还是想捕获第一个 组(名字)。
我使用了这个正则表达式,使姓氏部分成为可选的(在非捕获组中):
firstName:(.*)(?:-lastName:(.*))?
使用这个更新的正则表达式,生成的组是:
当 lastName 部分不存在时,例如 "firstName:Bill" 捕获的组是:
- 比尔
- /空字符串/
正确,
当 firstName 和 lastName 部分存在时:"firstName:Bill-lastName:Gates",分组不正确 :
- 比尔姓氏:盖茨
- /空/
我认为这与第一个捕获组的贪婪有关,但是当姓氏部分是可选的时,如何调整此正则表达式以使正则表达式工作?
你说的对,就是贪婪。找到第一个匹配组的分隔符。因此,如果您的名字 "never" 包含破折号,则只匹配除破折号以外的所有内容与第一个匹配组。
firstName:([^-]*)(?:-lastName:(.*))?
firstName:([^-]*)(?:-lastName:(.*))?
如果您找不到这样的分隔符,则需要采用不同的方法。即使您尝试创建第一个模式 "lazy",正则表达式引擎总是更喜欢 更大的 匹配,而不是匹配额外的可选匹配。
这是因为 lazy 匹配组将 匹配满足表达式 的第一个字符串(!重要的措辞!)
可能有一个带有 look arrounds 的选项,但您也可以使用 or 语句而不提供可选匹配项:
firstName:(.*)-lastName:(.*)|firstName:(.*)
这样,正则表达式引擎将匹配 or,但更喜欢具有 2 个匹配项的模式,因为它列在最前面。只有当那不适用时,它才会尝试单场比赛。
即使您已经接受了@dognose 的回答,我向您保证其中有带破折号的名字(您不想惹怒 Jean-Claude van Damme)。我建议你这样做:
firstName:((?:(?!-lastName:).)*)(?:-lastName:(.*))?
您可以从可视化中看到 (?:(?!-lastName:).)
表示 "if the current position is not followed by '-lastName:', capture another character"