请原谅我用 Python 编写我的解决方案,我对 Java 的了解不够,无法用 Java 编写。
pat = re.compile('(?=(?:([A-Z])|[0-9])' ## This part verifies that
'[^ ]*' ## there are at least one
'(?(1)\d|[A-Z]))' ## letter and one digit.
'('
'(?:(?<=[ ,])[A-Z0-9]|\A[A-Z0-9])' # start of second group
'[A-Z0-9-/\\\\]*'
'[A-Z0-9](?= |\Z|,)' # end of second group
')',
re.IGNORECASE) # this group 2 catches the string
.
我的解决方案在第二组中捕获了所需的字符串:((?:(?<={ ,])[A-Z0-9]|\A[A-Z0-9])[A-Z0-9-/\\\\]*[A-Z0-9](?= |\Z|,))
.
验证捕获的字符串中至少存在一个字母和一个数字之前的部分:
(?(1)\d|[A-Z]) 是一个条件正则表达式,意思是“如果 group(1) 抓到了东西,那么这里一定有一个数字,否则一定有一个字母”
组(1)是([A-Z]) in (?=(?:([A-Z])|[0-9])
(?:([A-Z])|[0-9]) 是一个非捕获组,它匹配一个字母(捕获的)或一个数字,所以当它匹配一个字母时,group(1) 不为空
.
标志 re.IGNORECASE 允许处理带有大写或小写字母的字符串。
.
在第二组中,我不得不写(?:(?<=[ ,])[A-Z0-9]|\A[A-Z0-9]),因为不允许使用非固定长度的后向断言。这部分表示一个字符,不能在 '-' 前面加上空格或字符串的头部。
相反,(?= |\Z[,) 表示“字符串结尾或逗号或空格之后”
.
此正则表达式假定字符 '-' 、 '/' 、 '\' 不能是捕获字符串的第一个字符或最后一个字符。对吗?
import re
pat = re.compile('(?=(?:([A-Z])|[0-9])' ## (from here) This part verifies that
'[^ ]*' # there are at least one
'(?(1)\d|[A-Z]))' ## (to here) letter and one digit.
'((?:(?<=[ ,])[A-Z0-9]|\A[A-Z0-9])'
'[A-Z0-9-/\\\\]*'
'[A-Z0-9](?= |\Z|,))',
re.IGNORECASE) # this group 2 catches the string
ch = "ALPHA13 10 ZZ 10-10 U-R open-office ,10B a10 UCS5000 -TR54 code vg4- DV-3000 SEA 300-BR gt4/ui bn\\3K"
print [ mat.group(2) for mat in pat.finditer(ch) ]
s = "A35, 35A, B503X,1ABC5 " +\
"AB-10, 10-AB, A10-BA, BA-A10, etc... " +\
"10-10, open-office, etc."
print [ mat.group(2) for mat in pat.finditer(s) ]
结果
['ALPHA13', '10B', 'a10', 'UCS5000', 'DV-3000', '300-BR', 'gt4/ui', 'bn\\3K']
['A35', '35A', 'B503X', '1ABC5', 'AB-10', '10-AB', 'A10-BA', 'BA-A10']