我遇到了一些奇怪的情况。
我正在尝试使用树梢来解析测量结果。
例如 - 1/2英寸的“铜管” 当然,这也可以写成英尺,英尺,英寸,英寸,英寸等。
所以我有一个规则
rule measurement ('\'' / 'Foot' / 'foot' / 'Feet' / 'feet' / '"' / 'Inches' / 'inches' / 'Inch' / 'inch' / 'cm' / 'cms' / 'Centimeters' / 'centimeters' / 'Centimeter' / 'centimeter' / 'm' / 'ms' / 'Meters' / 'meters'/ 'Meter' / 'meter' / 'lb' / 'lbs' / 'Pounds' / 'pounds' / 'Pound' / 'pound' ) (s? ')' / s) { def value [:measurement, text_value] end } end rule space [\s]+ end
当我输入'6英寸','6磅','6米'时,一切都很好,我得到了我的号码和测量结果。
当我输入'6米'时,米没有正确解析。
大多数测量工作正常,我在这里提供的测量中只忽略了“米”和“磅”(但我相信我将来会增加更多测量值。
关于为什么我会遇到这个问题的任何想法?
根据要求,完整语法的“减少”版本
grammar FullMeasurements rule full_product measures s? alternate_measure product_name { def value [:full_product, text_value] end } end rule measures single_measure / dual_measure / quantity { def measures [:measures, text_value] unless text_value.blank? end } end rule dual_measure quantity s? single_measure { def value [:dual_measure, text_value] unless text_value.blank? end } end rule alternate_measure '(' s? single_measure { def value [:alternate_measure, text_value] unless text_value.blank? end } end rule single_measure (range_number / number) s? measurement optional_secondary_measurements { def value [:single_measure, text_value] end } end rule optional_secondary_measurements measurement? { def value [:optional_secondary_measurements, text_value] end } end rule quantity (range_number / number) s? divisor? { def value [:quantity, text_value] end } end rule measurement ('\'' / 'Foot' / 'foot' / 'Feet' / 'feet' / '"' / 'Inches' / 'inches' / 'Inch' / 'inch' / 'cm' / 'cms' / 'Centimeters' / 'centimeters' / 'Centimeter' / 'centimeter' / 'm' / 'ms' / 'Meters' / 'meters'/ 'Meter' / 'meter' / 'lb' / 'lbs' / 'Pounds' / 'pounds' / 'Pound' / 'pound' ) (s? ')' / s) { def value [:measurement, text_value] end } end rule divisor "x" end rule product_name !measures words+ { def value [:product_name, text_value] end } end rule number frac_number / regular_number optional_frac { def value [:number, text_value] end } end rule optional_frac frac_number? { def value [:optional_frac, text_value] end } end rule frac_number (s? regular_number '/' regular_number) { def value [:frac_number, text_value] end } end rule words [0-9a-zA-Z\-()&.%'*\s]+ { def value text_value end } end rule regular_number [0-9\.]+ { def value text_value end } end rule space [\s]+ end end
答案 0 :(得分:1)
由于PEG是贪婪的并且/
是有序交替,因此您的measurement
规则与文字“meter”相匹配,然后您的语法失败,因为它无法找到以下内容与左边的“s”匹配的规则。与正则表达式不同,当后一个成功匹配失败时,PEG不会回溯之前的成功匹配。
将规则中的项目顺序切换为复数,然后你应该好好去。
答案 1 :(得分:0)
Phrogz在正确的轨道上,但它并不是“米”首先匹配,而是“m”没有任何东西可以匹配剩下的“eter”或“eters”。