Regex 单元提取的迭代法
有时会有一个数值范围,后跟一个测量单位。输入将是一个包含数字的文本字符串,后跟由函数提取的单位。给定一个包含数字和单位的文本字符串,以下内容可以将数字和单位提取为嵌套向量:Regex 单元提取的迭代法,regex,clojure,Regex,Clojure,有时会有一个数值范围,后跟一个测量单位。输入将是一个包含数字的文本字符串,后跟由函数提取的单位。给定一个包含数字和单位的文本字符串,以下内容可以将数字和单位提取为嵌套向量: (def aa ["meter" "kilometer"]) (def bb (clojure.string/join "|" aa)) (def cc (str "(\\d+)\\s*(" bb ")")) (def dd (re-pattern cc)) (defn foostring [strings]
(def aa ["meter" "kilometer"])
(def bb (clojure.string/join "|" aa))
(def cc (str "(\\d+)\\s*(" bb ")"))
(def dd (re-pattern cc))
(defn foostring [strings]
(into [] (map into [] (map (fn [[_ count unit]] {:count count, :unit unit})
(re-seq dd strings)))))
例如,让我们尝试输入:
(foostring "Today I sprinted 40 meters.")
输出将是:
[[[:count 40] [:unit meter]]]
但是,我无法提取后跟单位的数字范围,例如以下示例:
(foostring "Today I sprinted between 80-90 meters.")
该功能将为计数选择90,为单位选择仪表。然而,我正试图找出单元前面的数字范围
我认为可以提取这样的模式的想法是递归地查找“近邻”。也就是说,函数查找单元,然后查找单元左侧的数字。在“向左看”的过程中,函数可能会搜索一个数字,如前面提到的示例,一个数字后跟标点符号,即斜杠或一个单词。在上一次搜索的基础上展开,让我提供一个示例:
(foostring "Today I ran between 80 to 90 meters.")
或者,口语
(foostring“有8090只雪人在森林中奔跑。”)
虽然雪人的例子很奇怪,但在写的时候,它抓住了人们的演讲被翻译成文本的想法。一个可能发生这种情况的例子是在为一篇文章引用某人的过程中 试试这个:
(?i)(?<lowerBound>\d+)(?:\s*(?:-|to)\s*(?<upperBound>\d+))?\s+(?<unit>meters?|kilometers?|...)
(?i)(?\d+)(:\s*(?:-| to)\s*(?\d+))\s+(?米?|公里?|……)
描述
演示
(选择Java,因为Clojure与Java具有相同的风格)尝试以下方法:
(?i)(?<lowerBound>\d+)(?:\s*(?:-|to)\s*(?<upperBound>\d+))?\s+(?<unit>meters?|kilometers?|...)
(?i)(?\d+)(:\s*(?:-| to)\s*(?\d+))\s+(?米?|公里?|……)
描述
演示
(选择Java,因为Clojure与Java具有相同的风格)
我认为可以提取这种模式的想法将递归地寻找“近邻”
如果你真的是指递归,那么你肯定已经离开了正则表达式的领域。如果您对表达式不太感兴趣,可以使用上下文无关的EBNF
(require '[instaparse.core :as insta])
(def foostring
(insta/parser
"<S> = Expr+
Expr = <Stuff> Number+ {<[' '] [Preposition] [' ']> Number} <' '> Unit <Stuff>;
Bleh = #'[a-z A-Z.,]+';
Stuff = {Bleh}
Preposition = 'between'|'to'|'-';
Unit = 'meter'|'kilometer'|'Yeti'|'sandwiches';
Number = #'[0-9]+'"))
我认为可以提取这种模式的想法将递归地寻找“近邻”
如果你真的是指递归,那么你肯定已经离开了正则表达式的领域。如果您对表达式不太感兴趣,可以使用上下文无关的EBNF
(require '[instaparse.core :as insta])
(def foostring
(insta/parser
"<S> = Expr+
Expr = <Stuff> Number+ {<[' '] [Preposition] [' ']> Number} <' '> Unit <Stuff>;
Bleh = #'[a-z A-Z.,]+';
Stuff = {Bleh}
Preposition = 'between'|'to'|'-';
Unit = 'meter'|'kilometer'|'Yeti'|'sandwiches';
Number = #'[0-9]+'"))
对于这个特定的问题,请尝试类似于
“(\\d+)\\s*(?:-| to)(\\d+)”(\\d+)(“bb”)”
的方法。我刚刚尝试了一下,结果是“80-90米”。忘记了第二个可选空格:“(\\d+)\\s*(?:-| to)(\\d+)\\s*(“bb”)
,regex在80和90之间有斜线时选择了它们。但当80到90之间有一个空格时,它就不起作用了。此外,它将80作为上述函数中的计数输出,将90作为单位输出。然而,我担心这个正则表达式将无法拾取后跟一个单位的任意数字。例如“我午餐想吃2 3 4个三明治。”
如果你想在单词中寻找部分模式等等,你必须学习更多关于正则表达式的知识(即,除了一些简单的事情),并深入研究编写某种解析器。尝试类似“(\\d+\\s*(?:-| to)(\\d+)(\\d+)(“bb”)的东西
针对这个特定的问题。我刚刚尝试了一下,结果是“80-90米”。忘记了第二个可选空格:“(\\d+)\\s*(?:-| to)(\\d+)\\s*(“bb”)”
当80和90米之间有斜线时,正则表达式会拾取它们。但当80到90之间有一个空格时,它就不起作用了。此外,它将80作为上述函数中的计数输出,将90作为单位输出。然而,我担心这个正则表达式将无法拾取后跟一个单位的任意数字。例如“我午餐想吃2 3 4个三明治。”
如果你想在单词中寻找部分模式等,你必须学习更多关于正则表达式的知识(即,除了一些简单的事情),并深入研究编写某种解析器。有没有一种快速的方法使单元不区分大小写?(def insensitive foo(comp foostring clojure.string/lower case))
并用小写定义语法。是否有一种快速方法使单元不区分大小写?(def insensitive foo(comp foostring clojure.string/lower case))
并用小写定义语法。