在SAS中,我正在设置PXPARSE函数,以从调查的自由文本答案中提取有意义的信息。在大多数情况下,我这样做都是没有问题的。但是,尽管我已经尽了最大的努力,但我已经开始需要环顾四周,但现在却遇到了不正确的比赛。
这是正在评估的表达式:
hlhx=PRXPARSE('/yes|(?<!no).*homeless.*(for|in|year|age)|at\sage|couch|was\shomeless|multiple|
lived.*streets|(?<!\bnot).*at\srisk|has\sbeen|high\srisk|currently\shomeless|
liv(es|ing|ed).*car|many|(?<!\bno).*(hx|history|h.?o)|(?<!\bno)(?<!low).+risk/ox');
几个响应不应该与该表达式匹配,但是可以:
no hx of homelessness and low risk of homelessness
owns home, no h/o homelessness; low risk for homelessness
no and little risk
很显然,我没有正确指定我的隐身之处。任何帮助将不胜感激。
编辑:要说得更清楚一点,表达式的哪一部分导致与列表中的条目相匹配?
最好, 劳伦
答案 0 :(得分:1)
这是您的正则表达式与no and little risk
匹配的方式:
正则表达式中的一个分支是...|(?<!\bno)(?<!low).+risk
。
regex引擎首先在目标字符串中的每个位置尝试匹配,从头开始:
no and little risk
^
第一个约束是,当前位置不能在单词边界之后加上“ no”(由于(?<!\bno)
)。满足此条件:目标字符串的开头没有任何前缀。
第二个约束是当前位置不能以“ low”开头(由于(?<!low)
)。此条件也得到满足(请参见上文)。
然后,我们匹配一个或多个非换行符,但是要尽可能多地匹配它们(这是.+
部分)。在这里,我们首先使用整个字符串:
no and little risk
------------------^
但是正则表达式要求匹配risk
,该匹配失败(目标字符串中没有剩余的字符)。这会导致.+
回溯并消耗越来越少的字符,直到发生这种情况:
no and little risk
--------------^
此时,risk
成功匹配,并且正则表达式完成。
基本问题是您想做的是(?<!\bno.+)(?<!low.+)risk
,但是您写的是(?<!\bno)(?<!low).+risk
。这是两个截然不同的东西!
前者的意思是“匹配'risk',但前提是在字符串的任何位置(在'risk'之前最多1个字符)之前都没有'no'或'low'。后者的意思是“匹配任何非空的子字符串,后跟“风险”,只要它前面没有“否”或“低”。这使正则表达式引擎可以自由地在字符串中查找任何匹配的位置,只要它不立即以“ no”或“ low”开头,并且在某处后面是“。+ risk”即可。
不幸的是,(?<!\bno.+)
不是有效的正则表达式,因为后置断言必须具有固定的长度。
一种可能的解决方法是执行以下操作:
^(?!.*(?:\bno|low).+risk).*risk
这是说:从字符串的开头开始,首先确保没有“ no”或“ low”,然后在任何地方都没有“ risk”,然后在字符串中的任何地方匹配“ risk”。
这与(假设的)可变宽度后向版本并不完全等效,因为该版本已经匹配
risk no risk
^^^^
由于存在“风险”而没有“否”,因此首先找到了此解决方法
risk no risk
^^^^^^^
并立即拒绝整个字符串。