Regex 什么';使用scala拆分这行的合适正则表达式是什么?
我正在尝试拆分来自CSV文件的这一行,以从这一行(示例)中获得不同的匹配组(文件有大约750k行): 1919年,“世界末日”(via@annabosch)玛格丽特·撒切尔(86岁);艾尔·恩埃尔·帕克:,P,协议 正如你所看到的,这行有四个主要部分,id,自由文本,情绪,选项。另外,内容部分有很多字符(La dama de hierro…),我不知道如何构建一个正确的正则表达式来获得如下内容:(id,txt,sent,opt) 到目前为止,我所尝试的:Regex 什么';使用scala拆分这行的合适正则表达式是什么?,regex,scala,csv,Regex,Scala,Csv,我正在尝试拆分来自CSV文件的这一行,以从这一行(示例)中获得不同的匹配组(文件有大约750k行): 1919年,“世界末日”(via@annabosch)玛格丽特·撒切尔(86岁);艾尔·恩埃尔·帕克:,P,协议 正如你所看到的,这行有四个主要部分,id,自由文本,情绪,选项。另外,内容部分有很多字符(La dama de hierro…),我不知道如何构建一个正确的正则表达式来获得如下内容:(id,txt,sent,opt) 到目前为止,我所尝试的: val fullRegex = """(
val fullRegex = """(\d+),(.+?),(N|P|NEU|NONE)(,\W+|;\W+)re?""".r
对于某些行有效,但对于其他行无效。正如布鲁诺·格里德(Bruno Grieder)在对问题的评论中指出的那样,这可以更有力地处理 如果这不是一个格式良好的CSV文件(也就是说,包含引号的字段、转义字段值中的引号等),另一种方法是认识到第一个字段确实为您提供了ID,最后两个字段确实为您提供了情感和选项。其他内容都是自由文本,因此行的结构相当简单 当然,如果文件确实是格式良好的CSV,请使用为此目的构建的库 假设这不是格式良好的CSV,首先用逗号分割,将第一个和最后两个字段放入各自的变量中,并使用逗号连接其余字段以恢复文本 我不太懂Scala,所以代码相当原始。欢迎:
val line = """919191911919,"La dama de hierro descubrió la ternura".(via@annabosch) Margaret Thatcher (86 años); ayer en el parque: http://host.com/gm2EEXqn ,P,AGREEMENT"""
val id :: rest = line.split(",").toList
val text = rest.slice(0, rest.size - 2).mkString(",")
val sentiment = rest(rest.size - 2);
val option = rest.last;
for (x <- List(id, text, sentiment, option))
println(x)
这是您将获得的输出:
1
this is some text with one, two, three, and four commas (,)
7
8
1.
这是一些带有一、二、三和四个逗号(,)的文本
7.
8如果确定文本用双引号括起来,可以先替换双引号内的所有逗号,然后在逗号处拆分,然后将逗号放回原处。此解决方案的缺点是,您需要使用保证不在文件中的Unicode字符
object CSVFixer {
def main(args: Array[String]) {
split(line) foreach println
}
val line = """919191911919,"La dama de hierro descubrió la ternura".(via@annabosch) Margaret Thatcher (86 años); ayer en el parque: http://host.com/gm2EEXqn ,P,AGREEMENT"""
private val AltSep = '\u0080' // Unicode char that we reasonably expect to not have in the input
val fieldSeparator = ","
private[this] def unSep(s: String) = {
val SepChr = fieldSeparator.charAt(0)
var inQS = false
for (c <- s) yield {
c match {
case '"' =>
inQS = !inQS; c
case SepChr if inQS =>
AltSep
case _ => c
}
}
}
def split(line: String) =
unSep(line).split(fieldSeparator, -1) // do not discard trailing empty strings
.map(_.replace(AltSep, fieldSeparator.charAt(0)))
.map(_.replaceAll("\"", ""))
}
对象CSVFixer{
def main(参数:数组[字符串]){
分割(行)foreach println
}
val line=“”“919年”,第二天(via@annabosch)玛格丽特·撒切尔(86岁);艾尔·恩帕尔克:http://host.com/gm2EEXqn ,P,协议“”
private val AltSep='\u0080'//Unicode字符,我们有理由认为输入中不包含该字符
val fieldSeparator=“,”
private[this]def unsp(s:String)={
val SepChr=fieldSeparator.charAt(0)
var inQS=false
对于(c)
inQS=!inQS;c
如果inQS=>
阿尔塞普
案例uz=>c
}
}
}
def拆分(行:字符串)=
unsp(line).split(fieldSeparator,-1)//不要丢弃尾随的空字符串
.map(u.replace(AltSep,fieldSeparator.charAt(0)))
.map(\u0.replaceAll(“\”,“))
}
正则表达式功能强大,但有时很难正确处理并涵盖所有可能的输入格式。在这种情况下,可能不需要它
val in = """919191911919,"La dama de hierro descubrió la ternura".(via@annabosch) Margaret Thatcher (86 años); ayer en el parque: http://host.com/gm2EEXqn ,P,AGREEMENT"""
val inSplit = in.split(",")
val id = inSplit.head // String = 919191911919
val txt = inSplit.tail.init.init.mkString(",") // free form text
val sent = inSplit.init.last // String = P
val opt = inSplit.last // String = AGREEMENT
最简单的方法是
.splitBy(“,”)
,但是如果你有嵌套的逗号,它将不起作用。我建议你使用这样的方式:事实上@nmat,内容是自由文本,我不能期望它不包含逗号或任何其他字符。我将检查你提供的链接。任何与此regexp字符串不匹配的示例?假设字段数是固定的,我会检查。e、 您可以保证字段1、3、4中没有逗号,只需向前扫描到第一个逗号即可得到第一个字段,然后从末尾向后扫描到前两个逗号即可得到最后两个字段。第二个字段就是between@JorgeCespedes :)不是所有的问题都能用Regex或jQueryYes解决。这是我的建议。Regex并不是一根魔杖,它最适合所有的事情和工作anything@nmat是的,会的,看例子。@BrunoGrieder我在帖子下面看到了你最初的评论,我最初没有看到。
object CSVFixer {
def main(args: Array[String]) {
split(line) foreach println
}
val line = """919191911919,"La dama de hierro descubrió la ternura".(via@annabosch) Margaret Thatcher (86 años); ayer en el parque: http://host.com/gm2EEXqn ,P,AGREEMENT"""
private val AltSep = '\u0080' // Unicode char that we reasonably expect to not have in the input
val fieldSeparator = ","
private[this] def unSep(s: String) = {
val SepChr = fieldSeparator.charAt(0)
var inQS = false
for (c <- s) yield {
c match {
case '"' =>
inQS = !inQS; c
case SepChr if inQS =>
AltSep
case _ => c
}
}
}
def split(line: String) =
unSep(line).split(fieldSeparator, -1) // do not discard trailing empty strings
.map(_.replace(AltSep, fieldSeparator.charAt(0)))
.map(_.replaceAll("\"", ""))
}
val in = """919191911919,"La dama de hierro descubrió la ternura".(via@annabosch) Margaret Thatcher (86 años); ayer en el parque: http://host.com/gm2EEXqn ,P,AGREEMENT"""
val inSplit = in.split(",")
val id = inSplit.head // String = 919191911919
val txt = inSplit.tail.init.init.mkString(",") // free form text
val sent = inSplit.init.last // String = P
val opt = inSplit.last // String = AGREEMENT