我的任务是从文本中选择第一句话(我在C#
写作)。我认为最合适的方式是使用regex
,但发生了一些麻烦。我应该用什么正则表达式来选择第一句话?
几个例子:
第三个让我很困惑。
答案 0 :(得分:1)
因为你已经提供了一些假设:
句子用空格划分 任务是选择第一句
您可以使用以下正则表达式:
^.*?[.?!](?=\s+(?:$|\p{P}*\p{Lu}))
正则表达式细分:
^
- 字符串的开头(因此,只匹配第一个句子).*?
- 尽可能少的任意数量的字符(使用RegexOptions.Singleline
也可以将换行符与.
匹配)[.?!]
- 最后一个标点符号(?=\s+(?:$|\p{P}*\p{Lu}))
- 预测确保在字符串结尾(\s+
)或可选标点符号({{1)之后有一个或多个空白符号($
) }和)大写字母(\p{P}
)。<强>更新强>:
因为事实证明你可以输入单句,而你的句子可以以任何字母或数字开头,你可以使用
\p{Lu}
请参阅another demo
答案 1 :(得分:-1)
我提出了一个使用大量负面预测的正则表达式来排除某些情况,例如:标点符号必须不后面跟小写字符,或大写字母未关闭句子之前的点。这会将所有文本分成单独的句子。如果给你一个文本,只需参加第一场比赛。
[\s\S]*?(?![A-Z]+)(?:\.|\?|\!)(?!(?:\d|[A-Z]))(?! [a-z])/gm
答案 2 :(得分:-1)
应使用以下扫描仪搜索句子分隔符:
sentence-finisher
字符(如[。!?])
A sentence...
)Exclamation here!?
)sentence-finister
dialog-starter
字符(Blah blah blah... - And what next, Elric?
)提示:不要忘记在输入源字符串中添加额外的空格字符。
<强> UPD:强>
一些野生伪代码xD:
func sentence(inputString) {
finishers = ['.', '!', '?']
allowedSequences = ['.' => ['..'], '!' => ['!!', '?'], '?' => ['??', '!']]
input = inputString
result = ''
found = false
while input != '' {
finisherPos = min(pos(input, finishers))
if !finisherPos
return inputString
result += substr(input, 0, finisherPos + 1)
input = substr(input, finisherPos)
p = finisherPos
finisher = input[p]
p++
if input[p] != ' '
if match = testSequence(substr(input, p), allowedSequences[finisher]) {
result += match
found = true
break
} else {
continue
}
else {
p++
if input[p] in [A-Z] {
found = true
break
}
if input[p] in [0-9] {
p++
if input[p] in [a-z] or input[p] in finishers {
found = true
break
}
p--
}
if input[p] in ['-'] {
found = true;
break
}
}
}
if !found
return inputStr
return result
}
func testSequence(str, sequences) {
foreach (sequence: sequences)
if startsWith(str, sequence)
return sequence
return false
}