【问题标题】:How to extract the last value before last : character but after the last comma?如何提取最后一个值之前的最后一个值:字符但在最后一个逗号之后?
【发布时间】:2011-07-26 13:15:55
【问题描述】:

我正在使用 Clojure 解析和分析 XML 文件。
这是一个示例:

BSS:17,NSVC:1
BSS:17,NSVC:4
BSS:17,NSVC:5
BSS:17,BTSM:0,BTS:3
BSS:17,BTSM:0,BTS:4
BSS:17,BTSM:0,BTS:5
BSS:17,BTSM:1,BTS:0
BSS:17,BTSM:1,BTS:1
BSS:17,BTSM:1,BTS:2
BSS:17,BTSM:1,BTS:3

我对最后一个值感兴趣(在我的情况下,是最后一个逗号之后但最后一个 : 、NSVS 和 BTS 之前的值),它们之后的数字无关紧要。
如何提取前面字符串中的最后一个值?

【问题讨论】:

  • 如果你的名字/值总是 [A-Z] 和 [0-9] 这是一个非常简单的正则表达式:(A-Z)+:[0-9]+$
  • @Alex (re-seq #"(A-Z)+:[0-9]+$" "BSS:17,BTSM:14,BTS:4") 返回 nil

标签: string parsing clojure jvm


【解决方案1】:

您可以使用此函数来处理各个行:

(defn lastval [s]
  (second (re-find #",([^,:]+):\d*$" s)))
                 ;   ^ the comma preceding the interesting section
                 ;    ^ the part in parens will be captured as a group
                 ;     ^ character class meaning "anything except , or :"
                 ;            ^ the colon after the interesting section
                 ;             ^ any number of digits after the colon
                 ;                ^ end of string
          ; ^ returns a vector of [part-that-matches, first-group];
          ;   we're interested in the latter, hence second

注意。如果正则表达式不匹配,则返回 nil

例如:

user> (lastval "BSS:17,BTSM:0,BTS:3")
"BTS"

如果您以后想以易于使用的位提取所有信息,可以使用

(defn parse [s]
  (map (juxt second #(nth % 2)) (re-seq #"(?:^|,)([^,:]+):(\d+)" s)))

例如

user> (parse "BSS:17,BTS:0,BTS:3")
(["BSS" "17"] ["BTS" "0"] ["BTS" "3"])

【讨论】:

  • 如果我要和 Clojure 开发人员一起工作,我希望我能和你一起工作。世界级代码。我第一次阅读有关 juxt 功能的信息。谢谢。
  • 你用了re-find,为什么不用re-seq?
  • 乐于助人!我想你会发现这种代码在 Clojure 中相当普遍。 :-) 至于你的问题:re-find 只返回一个匹配项,如果有的话(如果你传递一个正则表达式和一个字符串,第一个;如果你传递一个 Matcher 对象,“下一个”一个;例如试试(let [m (re-matcher #"(foo|bar)" "foobar")] [(re-find m) (re-find m)]))。 re-seq 返回所有匹配的序列。因为在lastval 函数中我们只期望一个匹配,re-find 是完成这项工作的正确工具。请注意,上面的parse 确实使用了re-seq,因为它确实需要允许多个匹配项。
【解决方案2】:

你能用lastIndexOf 找到最后一个逗号吗?

【讨论】:

    【解决方案3】:

    这对你有用吗?

    (def tmp (str "BSS:17,NSVC:1\n BSS:17,NSVC:4\n BSS:17,NSVC:5\n BSS:17,BTSM:0,BTS:3\n BSS:17,BTSM:0,BTS:4\n BSS:17,BTSM:0,BTS:5\n BSS:17,BTSM:1,BTS:0\n BSS:17,BTSM:1,BTS:1\n BSS:17,BTSM:1,BTS:2\n BSS:17,BTSM:1,BTS:3\n")) (defn split [s sep] (->> (.split s sep) seq (filter #(not (empty? %))))) (reduce (fn[h v] (conj h (last v))) [] (map #(split % ",") (split tmp "\n")))

    我假设两行之间有某种分隔符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-12
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-14
      相关资源
      最近更新 更多