我需要将文本解析为句子,但我有一点问题。我在这个模式中使用正则表达式:
@"(?<=[\.!\?\...])\s+"
...从文本中分割句子。但是当我有这样的文字时:
Šios sutarties sąlygos taikomos „Microsoft. Hotmail“, „Microsoft. SkyDrive“, „Microsoft“ abonementui.
我需要正则表达式来分割所有句子,但它将它分成两个句子而不是:
Šios sutarties sąlygos taikomos „Microsoft.
Hotmail“, „Microsoft. SkyDrive“, „Microsoft“ abonementui.
如何编写正则表达式,忽略这些符号[. ! ? ...]
和„
之间的符号“
?
答案 0 :(得分:1)
就是这样。
以下是RE的一些细节:
(.*?„.*?“)*?
匹配0~无限组的some words outside „some words inside“
; [^„]*?(((?<!(\\d|\\b[A-Z]))\\.)|[!?])
将点.
或?
或!
,以及之前没有独立的„
转码; ((?<!(\\d|\\b[A-Z]))\\.)
上一项中on的子字符串,使点.
特殊,不应以单个大写字母或数字作为前缀; 小心所有*?
,确保我们没有过度匹配。
using System;
using System.Text.RegularExpressions;
namespace RegexTest
{
class MainClass
{
public static void Main(string[] args)
{
string[] cases =
{
"Šios sutarties sąlygos taikomos „Microsoft. Hotmail“, „Microsoft. SkyDrive“, „Microsoft“ abonementui.",
"Šios sutarties sąlygos taikomos „Microsoft“. Hotmail, „Microsoft. SkyDrive“, „Microsoft“ abonementui! Ok? more",
"1. Hello world. And MORE.",
"V. Hello world. And MORE.",
"1. V. Hello world. And MORE.",
"I am in room 102. And you?",
};
var re = new Regex("(.*?„.*?“)*?[^„]*?(((?<!\\b(\\d|[A-Z]))\\.)|[!?])");
foreach (var case_ in cases) {
foreach (Match m in re.Matches(case_))
Console.WriteLine(m);
Console.WriteLine("------------I am a splitter :) ------------");
}
}
}
}
输出:
Šios sutarties sąlygos taikomos „Microsoft. Hotmail“, „Microsoft. SkyDrive“, „Microsoft“ abonementui.
------------I am a splitter :) ------------
Šios sutarties sąlygos taikomos „Microsoft“.
Hotmail, „Microsoft. SkyDrive“, „Microsoft“ abonementui!
Ok?
------------I am a splitter :) ------------
1. Hello world.
And MORE.
------------I am a splitter :) ------------
V. Hello world.
And MORE.
------------I am a splitter :) ------------
1. V. Hello world.
And MORE.
------------I am a splitter :) ------------
I am in room 102.
And you?
------------I am a splitter :) ------------
答案 1 :(得分:0)
根据我的理解,你想匹配以?结尾的任何句子?和省略号'...'而忽略“”内的文字。您还希望不以任何单个数字或大写结尾匹配?!或者......
在这种情况下,这将有效:
([^„]*?(„[^“]+?“)*)+?(?<!\b[\dA-Z])([?!]|[.]{1,3})
代码示例:
public static void Main()
{
string pattern = @"([^„]*?(„[^“]+?“)*)+?(?<!\b[\dA-Z])([?!]|[.]{1,3})";
string input = "Šios sutarties sąlygos taikomos „Microsoft. Hotmail“, „Microsoft. SkyDrive“, „Microsoft“ abonementui.";
var matches = Regex.Matches( input, pattern );
foreach( Match match in matches )
{
Console.WriteLine(match.Value.Trim());
}
}
输出:
Šiosututiessąlygostakomos“微软。 Hotmail“,”微软。 SkyDrive“,”微软“abonementui。
输入:1.The „Acme. Photo“ is good. Test string „Microsoft. Hotmail“... Some more text? Even more text! Final text.
输出:
1.“Acme。照片“很好。
测试字符串“Microsoft。 Hotmail的“...
还有一些文字?
更多文字!
最终文本。
正则表达式的解释:([^„]*?(„[^“]+?“)*)+?(?<!\b[\dA-Z])([?!]|[.]{1,3})
[^„]*?
匹配任何不是'''的内容。 *?意味着懒惰的比赛(非贪婪)。([„][^“]+?[“])*
将此匹配与0“或更多”“+?
表示懒惰地匹配此次1次或多次(即之前的所有内容!,?,。,...)(?<!\b[\dA-Z])
表示对单个数字或大写字母执行负面后视。基本上,不匹配?!或......如果以数字或资本开头。([?!]|[.]{1,3})
表示匹配上一场比赛?要么 !或1至3。 (点/周期)通常我会使用(?&gt;)来提高性能,但我认为我们会保持正则表达式简单。 This site非常有帮助。
希望有所帮助。