Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance InputStream上的Scala正则表达式拆分_Performance_Scala_Functional Programming_Inputstream - Fatal编程技术网

Performance InputStream上的Scala正则表达式拆分

Performance InputStream上的Scala正则表达式拆分,performance,scala,functional-programming,inputstream,Performance,Scala,Functional Programming,Inputstream,我正在解析一个资源文件并使用以下代码在空行上拆分: val inputStream = getClass.getResourceAsStream("foo.txt") val source = scala.io.Source.fromInputStream(inputStream) val fooString = source.mkString val fooParsedSections = fooString.split("\\r\\n[\\f\\t ]*\\r\\n") 我相信这是将输入流

我正在解析一个资源文件并使用以下代码在空行上拆分:

val inputStream = getClass.getResourceAsStream("foo.txt")
val source = scala.io.Source.fromInputStream(inputStream)
val fooString = source.mkString
val fooParsedSections = fooString.split("\\r\\n[\\f\\t ]*\\r\\n")
我相信这是将输入流作为一个完整的字符串拉入内存,然后在正则表达式上拆分。这对于我正在解析的相对较小的文件来说效果很好,但并不理想,我很好奇如何改进它--

两个想法是:

  • 逐行读取输入流,并创建一个段缓冲区,在空行上拆分
  • 一个字符一个字符地读取流,并基于一个小型有限状态机解析段
  • 但是,如果可能的话,我不希望维护可变缓冲区

    有什么建议吗?这只是一个个人娱乐项目,我想学习如何以有效和实用的方式进行此操作。

    您可以使用方法获取空行前的前缀,然后重复。这里有一个帮助函数:

    def sections(lines: Stream[String]): Stream[String] = {
      if (lines.isEmpty) Stream.empty
      else {
        // cutting off the longest `prefix` before an empty line
        val (prefix, suffix) = lines.span { _.trim.nonEmpty }
        // dropping any empty lines (there may be several)
        val rest = suffix.dropWhile{ _.trim.isEmpty }
    
        // grouping back the prefix lines and calling recursion
        prefix.mkString("\n") #:: sections(rest)
      }
    }
    
    请注意,
    Stream
    的方法
    #::
    是惰性的,在需要之前不会计算正确的操作数。以下是如何将其应用于您的用例:

    val inputStream = getClass.getResourceAsStream("foo.txt")
    val source = scala.io.Source.fromInputStream(inputStream)
    val parsedSections = sections(source.getLines.toStream)
    
    方法返回迭代器[String],我们将其转换为
    Stream
    ,并应用helper函数。如果您在途中处理多组行而不需要存储它们,那么最后也可以调用
    .toIterator
    。详见文档

    编辑

    如果仍要使用正则表达式,可以将上述函数中的
    .trim.nonEmpty
    更改为使用
    字符串
    方法