我必须使用正则表达式从 swift 消息中解析 values 并且在某些情况下行为不是我想要的。
可以说我正在寻找具有特定模式的东西 - 在这种情况下是 BIC(6 个字母,后跟 2 个字母或数字,后跟可选的 XXX
或 3 位数字)
([A-Z]{6}[A-Z0-9]{2}[XXX0-9]{0,3})
这很好,但现在我想在特定领域寻找这些银行代码。在 swift 中,一个字段用 :
表示并且有一些数字,有时还有一个字母。
所以我想在字段 52A
中匹配 BIC value
我可以执行以下操作
(52A:[A-Z]{6}[A-Z0-9]{2}[XXX0-9]{0,3})
这将匹配 52A:AAAAAAAAXXX
我的问题是你可以在这个 value 之前和之后有东西 - 而 value 本身可能不存在于你想要的领域
所以我可以通配正则表达式以允许它之前的东西,例如
(52A:.*?[A-Z]{6}[A-Z0-9]{2}[XXX0-9]{0,3})
匹配 52A:somerubbishAAAAAAAAXXX
但如果此字段中没有任何内容 - 正则表达式会继续搜索模式,这就是我遇到问题的地方。
例如上面的 reg ex 匹配这个 52A:somerubbish:57D:AAAAAAAAXXX
问题
我需要 reg ex 在它之后的第一个字段上停止(它可能并不总是 57D
但它总是遵循格式 [0-9]{2}[A-Z]{0,1})
所以上面的例子不应该返回匹配,因为我之后的模式不是包含在 52A
部分
有谁知道我该怎么做?
回答1
将 .*?
更改为 [^:]*?
:
(52A:[^:]*?[A-Z]{6}[A-Z0-9]{2}[XXX0-9]{0,3})
[^:]
表示“除 : 之外的任何字符”,这确保匹配不会进入下一个字段。
查看https://rubular.com/r/wK5evDWKRtFRDp。
此外,除非您的情况要求您将目标匹配为第 1 组,否则您不需要外括号:整个匹配项(即第 0 组)将是您的目标。
我怀疑你想要 (XXX|\d{3})?
(XXX 或 3 位数字,但可选)或者 (XXX|\d{1,3})?
(XXX 或最多 3 位数字,但可选)而不是 [XXX0-9]{0,3}
回答2
使用 [XXX0-9]{0,3}
(与 [X0-9]{0,3}
相同)是字符类表示法,重复 0-3 次 X 字符或数字。
如果 value 本身也可以包含冒号,那么你可以将任何字符匹配为“垃圾”,只要直接在右边的不是字段格式即可。
52A:(?:(?![0-9]{2}[A-Z]?:).)*[A-Z]{6}[A-Z0-9]{2}(?:[0-9]{3}|XXX)?
模式匹配:
52A:
逐字匹配(?:(?![0-9]{2}[A-Z]?:).)*
匹配断言不是 2 位数字的任何字符,可选字符 A-Z 和 : 直接在右边[A-Z]{6}[A-Z0-9]{2}
匹配 6 个字符 A-Z 和 2 个字符 A-Z 或 0-9(?:[0-9]{3}|XXX)?
可选择匹配 3 位数字或 XXX