【问题标题】:Regex that match different format sentences in c#匹配c#中不同格式句子的正则表达式
【发布时间】:2013-03-01 02:09:52
【问题描述】:

文件格式

POS ID         PosScore NegScore    SynsetTerms                          Gloss
a   00001740    0.125   0           able#1"                              able to swim"; "she was able to program her computer";
a   00002098    0       0.75        unable#1                            "unable to get to town without a car"; 
a   00002312    0       0           dorsal#2 abaxial#1                  "the abaxial surface of a leaf is the underside or side facing away from the stem"
a   00002843    0       0           basiscopic#1                         facing or on the side toward the base
a   00002956    0       0.23        abducting#1 abducent#1               especially of muscles; drawing away from the midline of the body or from an adjacent part
a   00003131    0       0           adductive#1 adducting#1 adducent#1   especially of muscles; 

在这个文件中,我想提取 (ID,PosScore,NegScore and SynsetTerms) 字段。 (ID,PosScore,NegScore) 字段数据提取很简单,我对这些字段的数据使用以下代码。

Regex expression = new Regex(@"(\t(\d+)|(\w+)\t)");

var results = expression.Matches(input);
foreach (Match match in results)
{

    Console.WriteLine(match);
}
Console.ReadLine();  

它给出了正确的结果,但是 Filed SynsetTerms 会产生问题,因为有些行有两个或多个单词,所以如何组织单词并与之对抗 PosScore 和 NegScore。

例如,在第五行有两个词abducting#1abducent#1,但是两个词的分数是一样的。

那么,获取 Word 及其分数的行的正则表达式是什么,例如:

  Word                PosScore          NegScore 
  abducting#1         0                 0.23
  abducent#1          0                 0.23

【问题讨论】:

标签: c# regex


【解决方案1】:

非正则表达式,字符串拆分版本可能更容易:

var data =
   lines.Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
        .Skip(1)
        .Select(line => line.Split('\t'))
        .SelectMany(parts => parts[4].Split().Select(word => new
            {
                ID = parts[1],
                Word = word,
                PosScore = decimal.Parse(parts[2]),
                NegScore = decimal.Parse(parts[3])
            }));

【讨论】:

  • 标签以外的单个空格放在错误的位置可能真的会给事情带来麻烦。我想知道枚举字符串中的每个字符是否会更好。第一、第二、第三和第四列不包含任何空格,因此读取和存储直到下一个空格很容易。第五列中的每个项目都可以假定为列表的一部分,直到读者点击空格后跟双引号,标记第六列的开始,另一个双引号标记结束。唯一的问题是第六列中的每一项都需要用引号括起来。
  • @Tim:您发布的是有效答案。你应该用一些代码充实它并作为答案发布。
  • @AustinSalonen:这是 SentiWordNet 文件的格式,我想存储在数据库中你可以在这个Link中看到
  • @ZiaRehman:存储在数据库中超出了问题的范围......这将解析问题中定义的制表符分隔值。
【解决方案2】:

你可以使用这个正则表达式

^(?<pos>\w+)\s+(?<id>\d+)\s+(?<pscore>\d+(?:\.\d+)?)\s+(?<nscore>\d+(?:\.\d+)?)\s+(?<terms>(?:.*?#[^\s]*)+)\s+(?<gloss>.*)$

您可以创建这样的列表

var lst=Regex.Matches(input,regex)
             .Cast<Match>()
             .Select(x=>
             new 
             {
                 pos=x.Groups["pos"].Value,
                 terms=Regex.Split(x.Groups["terms"].Value,@"\s+"),
                 gloss=x.Groups["gloss"].Value
             }
        );

现在你可以迭代它

foreach(var temp in lst)
{
    temp.pos;
    //you can now iterate over terms
    foreach(var t in temp.terms)
    {
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-05
    • 1970-01-01
    • 2019-09-12
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多