scala - 关闭!!我如何从 Scala 中的字符串中检测类型?

标签 scala csv pattern-matching string-matching opencsv

我正在尝试解析 csv 文件,并且需要从字符串值开始确定每个字段的类型。

例如:

val row: Array[String] = Array("1/1/06 0:00","3108 OCCIDENTAL DR","3","3C","1115")

这就是我会得到的:

row(0) --> Date
row(1) --> String
row(2) --> Int
Ecc....

我该怎么办?

------------------------------------ 解决方案 --- ---------------------------------

这是我发现的识别字符串、日期、整数、 double 和 bool 值字段的解决方案。 希望以后有人可以服务。

  def typeDetection(x: String): String = {
    x match {
      // Matches: [12], [-22], [0] Non-Matches: [2.2], [3F]
      case int if int.matches("^-?[0-9]+$") => "Int"
      // Matches: [2,2], [-2.3], [0.2232323232332] Non-Matches: [.2], [,2], [2.2.2]
      case double if double.matches("^-?[0-9]+(,|.)[0-9]+$") => "Double"
        // Matches: [29/02/2004 20:15:27], [29/2/04 8:9:5], [31/3/2004 9:20:17] Non-Matches: [29/02/2003 20:15:15], [2/29/04 20:15:15], [31/3/4 9:20:17]
      case d1 if d1.matches("^((((31\\/(0?[13578]|1[02]))|((29|30)\\/(0?[1,3-9]|1[0-2])))\\/(1[6-9]|[2-9]\\d)?\\d{2})|(29\\/0?2\\/(((1[6-9]|[2-9]\\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))|(0?[1-9]|1\\d|2[0-8])\\/((0?[1-9])|(1[0-2]))\\/((1[6-9]|[2-9]\\d)?\\d{2})) *(?:(?:([01]?\\d|2[0-3])(\\-|:|\\.))?([0-5]?\\d)(\\-|:|\\.))?([0-5]?\\d)")
        => "Date"
        // Matches: [01.1.02], [11-30-2001], [2/29/2000] Non-Matches: [02/29/01], [13/01/2002], [11/00/02]
      case d2 if d2.matches("^(?:(?:(?:0?[13578]|1[02])(\\/|-|\\.)31)\\1|(?:(?:0?[1,3-9]|1[0-2])(\\/|-|\\.)(?:29|30)\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:0?2(\\/|-|\\.)29\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\\/|-|\\.)(?:0?[1-9]|1\\d|2[0-8])\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$")
        => "Date"
        // Matches: [12/01/2002], [12/01/2002 12:32:10] Non-Matches: [32/12/2002], [12/13/2001], [12/02/06]
      case d3 if d3.matches("^(([0-2]\\d|[3][0-1])(\\/|-|\\.)([0]\\d|[1][0-2])(\\/|-|\\.)[2][0]\\d{2})$|^(([0-2]\\d|[3][0-1])(\\/|-|\\.)([0]\\d|[1][0-2])(\\/|-|\\.)[2][0]\\d{2}\\s([0-1]\\d|[2][0-3])\\:[0-5]\\d\\:[0-5]\\d)$")
        => "Date"
      case boolean if boolean.equalsIgnoreCase("true") || boolean.equalsIgnoreCase("false") => "Boolean"
      case _ => "String"
    }

}

最佳答案

val row: Array[String] = Array("1/1/06 0:00","3108 OCCIDENTAL DR","3","3C","1115")

val types: Array[String] = row.map(x => x match {
  case string if string.contains("/") => "Date probably"
  case string if string.matches("[0-9]+") => "Int probably"
  case _ => "String probably"
})


types.foreach( x => println(x))

输出:

Date probably
String probably
Int probably
String probably
Int probably

但说实话,我不会使用这种方法,这很容易出错,而且有很多事情可能会出错,我什至不想考虑它,最简单的例子是如果一个字符串包含一个 /,这一小段代码将作为 Date 进行匹配。

我不知道你的用例,但根据我的经验,创建一些试图猜测不安全数据类型的东西总是一个坏主意,如果你可以控制它,你可以引入一些标识符,例如 "1/1/06 0:00 %d%" 其中 %d% 将指示日期等,然后将其从字符串中删除,即使如此,您也永远不会100% 确信这不会失败。

关于scala - 关闭!!我如何从 Scala 中的字符串中检测类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23656672/

相关文章:

f# - 使用 'flexible' 类型参数对泛型类型进行模式匹配

scala - 尝试实例化命名(注释)类

scala - 惯用的 scala 代码的好例子

Scala:收集不可变状态的更新/更改

c - fgets 在读到 csv 末尾之前停止,并且输出错误

java - 复杂的 Java 对象到 CSV

python - pandas to_csv 参数 float_format 和 decimal 不适用于索引列

python - 如何比较两列中的字符串并将一列中的字符串大小写替换为另一列?

java - WatchService 在集成测试中不起作用

rust - 哪种获取结构字段引用的方法是首选方法?