2017-01-07 4 views
1

у меня есть небольшое задание, где у меня есть статья в формате, как этоРасщепление статьи предложений с использованием разделителей

<REUTERS TOPICS="NO" LEWISSPLIT="TRAIN" CGISPLIT="TRAINING-SET" OLDID="5545" NEWID="2"> 
<TITLE>STANDARD OIL &lt;SRD> TO FORM FINANCIAL UNIT</TITLE> 
<DATELINE> CLEVELAND, Feb 26 - </DATELINE><BODY>Standard Oil Co and BP North America 
Inc said they plan to form a venture to manage the money market 
borrowing and investment activities of both companies. 
BP North America is a subsidiary of British Petroleum Co 
Plc &lt;BP>, which also owns a 55 pct interest in Standard Oil. 
The venture will be called BP/Standard Financial Trading 
and will be operated by Standard Oil under the oversight of a 
joint management committee. 

Reuter 
&#3;</BODY></TEXT> 
</REUTERS> 

и я пишу его в новый файл XML с этим форматом

<article id= some id > 
     <subject>articles subject </subject> 
     <sentence> sentence #1 </sentence> 
     . 
     . 
     . 
     <sentence> sentence #n </sentence> 
</article> 

Я написал код, который делает все это и отлично работает.

Проблема заключается в том, что я разделяю предложения, используя разделитель ., но если число есть номер 2.00, код считает, что 2 является предложением, а 00 - другим предложением.

Есть ли у кого-нибудь идеи о том, как лучше определять предложения, чтобы они сохраняли числа и тому подобное предложение?

Без необходимости проходить через весь массив?

Есть ли способ, которым я могу иметь метод string.Split() игнорировать разделение, если есть число до и после разделителя?

Мой код:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.IO; 
using System.Data; 
using System.Xml; 
namespace project 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string[] lines = System.IO.File.ReadAllLines(@"path"); 
      string body = ""; 
      REUTERS article = new REUTERS(); 
      string sentences = ""; 
      for (int i = 0; i<lines.Length;i++){ 
       string line = lines[i]; 
       // finding the first tag of the article 
       if (line.Contains("<REUTERS")) 
       { 
        //extracting the id from the tag 
        int Id = line.IndexOf("NEWID=\"") + "NEWID=\"".Length; 
        article.NEWID = line.Substring(Id, line.Length-2 - Id); 
       } 
       if (line.Contains("TITLE")) 
       { 
        string subject = line; 
        subject = subject.Replace("<TITLE>", "").Replace("</TITLE>", ""); 

        article.TITLE = subject; 
       } 
       if(line.Contains("<BODY")) 
       { 
        int startLoc = line.IndexOf("<BODY>") + "<BODY>".Length; 
        sentences = line.Substring(startLoc, line.Length - startLoc);  
        while (!line.Contains("</BODY>")) 
        { 
         i++; 
         line = lines[i]; 
         sentences = sentences +" " + line; 
        } 
        int endLoc = sentences.IndexOf("</BODY>"); 
        sentences = sentences.Substring(0, endLoc); 
        char[] delim = {'.'}; 
        string[] sentencesSplit = sentences.Split(delim); 

        using (System.IO.StreamWriter file = 
         new System.IO.StreamWriter(@"path",true)) 
        { 
         file.WriteLine("<articles>"); 
         file.WriteLine("\t <article id = " + article.NEWID + ">"); 
         file.WriteLine("\t \t <subject>" + article.TITLE + "</subject>"); 

         foreach (string sentence in sentencesSplit) 
         { 
          file.WriteLine("\t \t <sentence>" + sentence + "</sentence>"); 
         } 
         file.WriteLine("\t </article>"); 
         file.WriteLine("</articles>"); 
        } 
       } 
      } 
     } 

     public class REUTERS 
     { 
      public string NEWID; 
      public string TITLE; 
      public string Body; 
     } 
    } 
} 
+3

разделенным на '' точка, то пространство, так как большинство предложений имеют белое пространство после «» полная остановка. вы также можете включить разрывы строк. это похоже на что-то для регулярного выражения. – Nkosi

+0

метод split, хотя возвращает char [], поэтому я не могу сделать «.», Так как это строка, а не char –

+0

использовать '... .ToCharArray()' then. – FINDarkside

ответ

0

нормально, так что я нашел решение, используя идеи, которые я получил здесь я использовал метод перегрузки раскола, как этот

.Split(new string[] { ". " }, StringSplitOptions.None); 

и он выглядит намного лучше

+0

Если это сработает для вас, что-то не так с вашим вопросом. В вашем вопросе точкам, которые заканчивают предложения, не следует пробел. В любом случае это кажется ненадежным, поскольку период, за которым не следует пробел, может по-прежнему заканчивать предложение, например, если за ним следует закрывающая кавычка, а затем пробел. – hvd

0

Вы также можете использовать регулярное выражение, которое ищет терминаторы предложений с пробелами:

var pattern = @"(?<=[\.!\?])\s+"; 
var sentences = Regex.Split(input, pattern); 

foreach (var sentence in sentences) { 
    //do something with the sentence 
    var node = string.Format("\t \t <sentence>{0}</sentence>", sentence); 
    file.WriteLine(node); 
} 

Обратите внимание, что это относится к английскому языку, так как могут быть другие правила для предложений на других языках.

Этот пример

using System; 
using System.Text.RegularExpressions; 

public class Program 
{ 
    public static void Main() 
    { 
     var input = @"Standard Oil Co and BP North America 
Inc said they plan to form a venture to manage the money market 
borrowing and investment activities of both companies. 
BP North America is a subsidiary of British Petroleum Co 
Plc <BP>, which also owns a 55 pct interest in Standard Oil. 
The venture will be called BP/Standard Financial Trading 
and will be operated by Standard Oil under the oversight of a 
joint management committee."; 
     var pattern = @"(?<=[\.!\?])\s+"; 
     var sentences = Regex.Split(input, pattern); 
     foreach (var sentence in sentences) 
     { 
      var innerText = sentence.Replace("\n", " ").Replace('\t', ' '); 
      //do something with the sentence 
      var node = string.Format("\t \t <sentence>{0}</sentence>", innerText); 
      Console.WriteLine(node); 
     } 
    } 
} 

Производит этот выход

 <sentence>Standard Oil Co and BP North America Inc said they plan to form a venture to manage the money market borrowing and investment activities of both companies.</sentence> 
     <sentence>BP North America is a subsidiary of British Petroleum Co Plc <BP>, which also owns a 55 pct interest in Standard Oil.</sentence> 
     <sentence>The venture will be called BP/Standard Financial Trading and will be operated by Standard Oil under the oversight of a joint management committee.</sentence> 
0

я бы составить список всех точек индекса для '' персонажи.

точка указателя foreach, проверяйте каждую сторону для чисел, если числа находятся с обеих сторон, удалите указатель из списка.

Затем, когда вы выходите, просто используйте функции подстроки с остальными индексными точками, чтобы получить каждое предложение как отдельное лицо.

код Плохого качества следующим образом (это поздно):

List<int> indexesToRemove = new List<int>(); 
int count=0; 
foreach(int indexPoint in IndexPoints) 
{ 
    if((sentence.elementAt(indexPoint-1)>='0' && elementAt(indexPoint-1<='9')) && (sentence.elementAt(indexPoint+1)>='0' && elementAt(indexPoint+1<='9'))) 
     indexesToRemove.Add(count); 
    count++; 
} 

Следующая строка, так что мы не должны изменять количество удаления, как мы пересекаем список в последнем шаге.

indexesToRemove = indexesToRemove.OrderByDescending(); 

Теперь мы просто удаляем все местоположения '.', Которые имеют номера с обеих сторон.

foreach(int indexPoint in indexesToRemove) 
{ 
    IndexPoints.RemoveAt(indexPoint); 
} 

Теперь, когда вы зачитываете предложения в новый формат файл, который вы только петли sentences.substring(lastIndexPoint+1, currentIndexPoint)

0

потратил много времени на это - думал, что вы хотели бы видеть его, как он на самом деле не использует неудобный код что бы то ни было - он производит выход на 99%, аналогичный вашему.

<articles> 
    <article id="2"> 
     <subject>STANDARD OIL &lt;SRD&gt; TO FORM FINANCIAL UNIT</subject> 
     <sentence>Standard Oil Co and BP North America</sentence> 
     <sentence>Inc said they plan to form a venture to manage the money market</sentence> 
     <sentence>borrowing and investment activities of both companies.</sentence> 
     <sentence>BP North America is a subsidiary of British Petroleum Co</sentence> 
     <sentence>Plc &lt;BP&gt;, which also owns a 55.0 pct interest in Standard Oil.</sentence> 
     <sentence>The venture will be called BP/Standard Financial Trading</sentence> 
     <sentence>and will be operated by Standard Oil under the oversight of a</sentence> 
     <sentence>joint management committee.</sentence> 
    </article> 
</articles> 

приложение консоли выглядит следующим образом:

using System.Xml; 
using System.IO; 

namespace ReutersXML 
{ 
    class Program 
    { 
     static void Main() 
     { 
      XmlDocument xmlDoc = new XmlDocument(); 

      xmlDoc.Load("reuters.xml"); 

      var reuters = xmlDoc.GetElementsByTagName("REUTERS"); 
      var article = reuters[0].Attributes.GetNamedItem("NEWID").Value; 
      var subject = xmlDoc.GetElementsByTagName("TITLE")[0].InnerText; 
      var body = xmlDoc.GetElementsByTagName("BODY")[0].InnerText; 

      string[] sentences = body.Split(new string[] { System.Environment.NewLine }, 
       System.StringSplitOptions.RemoveEmptyEntries); 

      using (FileStream fileStream = new FileStream("reuters_new.xml", FileMode.Create)) 
      using (StreamWriter sw = new StreamWriter(fileStream)) 
      using (XmlTextWriter xmlWriter = new XmlTextWriter(sw)) 
      { 
       xmlWriter.Formatting = Formatting.Indented; 
       xmlWriter.Indentation = 4; 

       xmlWriter.WriteStartElement("articles"); 
       xmlWriter.WriteStartElement("article"); 
       xmlWriter.WriteAttributeString("id", article); 
       xmlWriter.WriteElementString("subject", subject); 

       foreach (var s in sentences) 
        if (s.Length > 10) 
         xmlWriter.WriteElementString("sentence", s); 

       xmlWriter.WriteEndElement(); 
      } 
     } 
    } 
} 

Я надеюсь, вам понравится :)

Смежные вопросы