2009-12-20 34 views
22

Tôi đang tìm một biểu thức chính quy .NET tốt mà tôi có thể sử dụng để phân tích cú pháp các câu riêng lẻ từ một phần văn bản.Cụm từ thông dụng để phân tích cú pháp các câu riêng lẻ là gì?

Nó sẽ có thể phân tích các khối sau đây của văn bản vào đúng sáu câu:

Hello world! How are you? I am fine. 
This is a difficult sentence because I use I.D. 

Newlines should also be accepted. Numbers should not cause 
sentence breaks, like 1.23. 

này được chứng minh khó khăn hơn một chút so với tôi nghĩ ban đầu.

Mọi trợ giúp sẽ được đánh giá cao. Tôi sẽ sử dụng điều này để đào tạo hệ thống trên các phần văn bản đã biết.

+0

@Luke: Nó trông giống như bạn muốn có một ngắt dòng rõ ràng giữa "nguyên nhân" và "câu" trong văn bản mẫu của bạn, nhưng nó không được hiển thị. Tôi buộc nó hiển thị bằng cách chèn hai dấu cách trước dòng cấp. Đó là cách bạn muốn nó nhìn, phải không? –

+0

Có, bạn đang phát hiện! Cảm ơn bạn đã sửa lỗi này. Silly me (vẫn là một noob). –

Trả lời

36

Hãy thử điều này @"(\S.+?[.!?])(?=\s+|$)":

string [email protected]"Hello world! How are you? I am fine. This is a difficult sentence because I use I.D. 
Newlines should also be accepted. Numbers should not cause sentence breaks, like 1.23."; 

Regex rx = new Regex(@"(\S.+?[.!?])(?=\s+|$)"); 
foreach (Match match in rx.Matches(str)) { 
    int i = match.Index; 
    Console.WriteLine(match.Value); 
} 

Kết quả:

Hello world! 
How are you? 
I am fine. 
This is a difficult sentence because I use I.D. 
Newlines should also be accepted. 
Numbers should not cause sentence breaks, like 1.23. 

Đối với những phức tạp, tất nhiên, bạn sẽ cần một phân tích cú pháp thực như SharpNLP hoặc NLTK. Mỏ chỉ là một cái nhanh và bẩn.

Dưới đây là các thông tin SharpNLP, và các tính năng:

SharpNLP là một tập hợp các công cụ xử lý ngôn ngữ tự nhiên viết bằng C#. Hiện nay nó cung cấp các công cụ NLP sau:

  • một splitter câu
  • một tokenizer
  • một phần-of-speech tagger
  • một chunker (dùng để "tìm chú thích cú pháp không đệ quy chẳng hạn như các cụm từ danh từ ")
  • một trình phân tích cú pháp
  • công cụ tìm kiếm tên
  • a coreference cụ
  • một giao diện cơ sở dữ liệu từ vựng WordNet
+3

+1 để trỏ chúng tôi đến SharpNLP mà tôi chưa từng thấy trước đây và có thể rất hữu ích. –

+0

Sử dụng tốt hơn xác nhận xem trước cho '(?: \ S + | $)'. – Gumbo

+0

Cảm ơn thông tin Gumbo, nó tốt hơn, nhưng tôi phải thêm \ S ở phía trước, bởi vì khoảng trống phải nằm ở bên trái. – YOU

2

này là không thực sự tốt với chỉ biểu thức thông thường, trừ khi bạn biết chính xác mà thẻ "khó khăn" mà bạn có, chẳng hạn như "id", "Ông" , v.v. Ví dụ: có bao nhiêu câu là "Vui lòng hiển thị ID của bạn, ông Bond".? Tôi không quen thuộc với bất kỳ C#-thực hiện, nhưng tôi đã sử dụng NL2 của Punkt tokenizer. Có lẽ không nên quá khó để thực hiện lại.

5
var str = @"Hello world! How are you? I am fine. This is a difficult sentence because I use I.D. 
Newlines should also be accepted. Numbers should not cause sentence breaks, like 1.23."; 

Regex.Split(str, @"(?<=[.?!])\s+").Dump(); 

Tôi đã thử nghiệm điều này trong LINQPad.

+0

Cảm ơn bạn đã dùng thử. –

5

Không thể sử dụng các regex để phân tích ngôn ngữ tự nhiên. Phần cuối của câu là gì? Một khoảng thời gian có thể xảy ra ở nhiều nơi (ví dụ:). Bạn nên sử dụng một bộ công cụ phân tích ngôn ngữ tự nhiên như OpenNLP hoặc NLTK. Thật không may, có rất ít, nếu có, các dịch vụ trong C#. Do đó, bạn có thể phải tạo một webservice hoặc liên kết với C#.

Lưu ý rằng nó sẽ gây ra sự cố trong tương lai nếu bạn dựa vào khoảng trắng chính xác như trong "I.D.". Bạn sẽ sớm tìm thấy các ví dụ phá vỡ regex của bạn. Ví dụ, hầu hết mọi người đặt không gian sau khi họ intials.

Có bản tóm tắt tuyệt vời về các dịch vụ mở và thương mại trong WP (http://en.wikipedia.org/wiki/Natural_language_processing_toolkits). Chúng tôi đã sử dụng một số trong số họ. Đó là giá trị nỗ lực.

[Bạn sử dụng từ "tàu". Điều này thường được kết hợp với máy học (đó là một cách tiếp cận NLP và đã được sử dụng để phân tách câu). Thật vậy, các bộ công cụ tôi đã đề cập bao gồm học máy. Tôi nghi ngờ đó không phải là những gì bạn có nghĩa là - thay vì bạn sẽ phát triển biểu hiện của bạn thông qua chẩn đoán. Đừng]

+0

THanks cho thông tin đó. Tôi luôn tò mò về khía cạnh máy học của điều này và đây là một khía cạnh mà tôi muốn điều tra. Đối với mục đích hiện tại của tôi, tôi thực sự nghĩ rằng phương pháp regex đơn giản (nơi tôi không mong đợi những trường hợp kỳ lạ mà bạn nói đến) là tốt. Tuy nhiên, tôi sẽ thử các khuôn khổ mà bạn nói vì chúng đã tồn tại. –

0

tôi đã sử dụng những gợi ý được đăng ở đây và đã đưa ra các regex rằng vỉa để đạt được những gì tôi muốn làm:

(?<Sentence>\S.+?(?<Terminator>[.!?]|\Z))(?=\s+|\Z) 

tôi đã sử dụng Expresso để đến với:

// using System.Text.RegularExpressions; 
/// <summary> 
/// Regular expression built for C# on: Sun, Dec 27, 2009, 03:05:24 PM 
/// Using Expresso Version: 3.0.3276, http://www.ultrapico.com 
/// 
/// A description of the regular expression: 
/// 
/// [Sentence]: A named capture group. [\S.+?(?<Terminator>[.!?]|\Z)] 
///  \S.+?(?<Terminator>[.!?]|\Z) 
///   Anything other than whitespace 
///   Any character, one or more repetitions, as few as possible 
///   [Terminator]: A named capture group. [[.!?]|\Z] 
///    Select from 2 alternatives 
///     Any character in this class: [.!?] 
///     End of string or before new line at end of string 
/// Match a suffix but exclude it from the capture. [\s+|\Z] 
///  Select from 2 alternatives 
///   Whitespace, one or more repetitions 
///   End of string or before new line at end of string 
/// 
/// 
/// </summary> 
public static Regex regex = new Regex(
     "(?<Sentence>\\S.+?(?<Terminator>[.!?]|\\Z))(?=\\s+|\\Z)", 
    RegexOptions.CultureInvariant 
    | RegexOptions.IgnorePatternWhitespace 
    | RegexOptions.Compiled 
    ); 


// This is the replacement string 
public static string regexReplace = 
     "$& [${Day}-${Month}-${Year}]"; 


//// Replace the matched text in the InputText using the replacement pattern 
// string result = regex.Replace(InputText,regexReplace); 

//// Split the InputText wherever the regex matches 
// string[] results = regex.Split(InputText); 

//// Capture the first Match, if any, in the InputText 
// Match m = regex.Match(InputText); 

//// Capture all Matches in the InputText 
// MatchCollection ms = regex.Matches(InputText); 

//// Test to see if there is a match in the InputText 
// bool IsMatch = regex.IsMatch(InputText); 

//// Get the names of all the named and numbered capture groups 
// string[] GroupNames = regex.GetGroupNames(); 

//// Get the numbers of all the named and numbered capture groups 
// int[] GroupNumbers = regex.GetGroupNumbers(); 
0

Hầu hết đều khuyên bạn nên sử dụng SharpNLP và có thể bạn nên làm như vậy trừ khi bạn muốn phòng QA của bạn có liên kết lỗi.

Nhưng vì bạn có thể bị áp lực. Đây là một nỗ lực khác để xử lý các từ như "Dr." và "X.". Nhưng, nó sẽ thất bại với một câu kết thúc bằng "nó".

Xin chào mọi người! Bạn khỏe không? Tôi ổn. Đây là câu khó vì tôi sử dụng I.D. Các dòng mới cũng phải được chấp nhận. Số điện thoại không được gây ra các dấu chấm câu, như 1.23. Xem Bác sĩ B hoặc ông FooBar để đánh giá H. pylori trong chứng tim.

var result = new Regex(@"(\S.+?[.!?])(?=\s+|$)(?<!\s([A-Z]|[a-z]){1,3}.)").Split(input).Where(s => !String.IsNullOrWhiteSpace(s)).ToArray<string>(); 
    foreach (var match in result) 
    { 
     Console.WriteLine(match); 
    } 
Các vấn đề liên quan