我是regex的新手,我正在尝试创建一个正则表达式来匹配一个字符串,该字符串包含以英尺和英寸表示的度量值,以及以英寸为单位的小数值的可能性。到目前为止,我有以下表达式:
var rex =/\s*(\d+)?\s*(?:'|ft|ft.|feet)?\s*-?\s*(\d+)?\s*(\d+)?\/?(\d+)?\s*(?:''|"|in|in.|inches)?/
为了尽可能灵活,我将所有捕获设置为可选,以将1ft
或5''
等测量值设置为有效输入数据。
var mstring = '5in';
var match = rex.exec(mstring);
问题在于,当应用正则表达式时,例如5in
,我获得的捕获是match[1]='5'
,而其他三个值(match[2]
,match[3]
和match[4]
)仍为undefined
。
是否有一种方法可以按照定义的顺序显示捕获的值?
在上述情况下,match[2]="5in"
match[1]
,match[3]
和match[4]
仍为undefined
。
答案 0 :(得分:1)
诀窍是在可选部分周围使用非捕获组并在这些组中使用强制子模式:
var rex =/(?:\s*(\d+)\s*(?:feet|ft\.|ft|'))?(?:\s*-\s*(\d+))?(?:\s*(\d+)\/)?(?:(\d+)\s*(?:inches|in\.|in|''|"))?/
在第1组中,我强制要求(?:feet|ft\.|ft|')
,在第2组中,它是第3组中的连字符-
,斜杠/
,在第4组中,它是(?:inches|in\.|in|''|")
轮流。
请参阅demo
我现在不理解逻辑,但是如果您希望5
中的5in
出现在第二组中,请使用
(?:\s*(\d+)\s*(?:feet|ft\.|ft|'))?(?:\s*-?\s*(\d+))?(?:\s*(\d+)\/)?(?:(\d+)\s*(?:inches|in\.|in|''|"))?
^
请参阅Demo 2
答案 1 :(得分:0)
我会考虑做一些预处理 - 删除所有空格并对输入进行一些转换。例如:
// normalize the input, e.g. 5 feet 11 inches becomes 5'11"
// any non-numerical character sequence starting with f is considering feet measurement, similar for inches (i.e. starting with i)
text = text.replace(/[^A-Z0-9'"]*/gi, '').replace(/f[^0-9]*/, "'").replace(/i[^0-9]*/, '"');
// regexp becomes simpler
var re = /(\d+')?(\d+")?/