如何使用Javascript正则表达式检测没有注释和标记的句子



问题

我有一段文字。它可以包含从ASCII 32(空格(到ASCII 126(波浪号(的每个字符,并包括ASCII 9(水平制表符(。

文本可能包含句子。每个句子都以句点、问号或感叹号结尾,后面紧跟空格。

文本可能包含基本的标记样式,即:粗体文本(**,也称为__(、斜体文本(*,也称为_(和删除线(~~(。标记可能出现在句子内部(例如**this** is a sentence.(或句子外部(例如**this is a sentence!**(。Markdown可能不会出现在句子之间,也就是说,可能不会出现这样的情况:**sentence. sente** nce.。Markdown可能包括多个句子,也就是说,可能出现这样的情况:**sentence. sentence.**

它还可以包含两个字符序列:<!---->。这些序列之间的所有内容都被视为注释(就像在HTML中一样(。注释可以出现在文本的每个位置,但不能包含换行符(我希望在Linux上它只是ASCII 10(。

我想在Javascript中检测所有的句子,并在注释中把每个句子的长度放在这个句子后面,比如:sentence.<!-- 9 -->主要是,我不在乎它们的长度是否包括markdown标签的长度,但如果没有,那就太好了。

到目前为止我做了什么

到目前为止,在这个答案的帮助下,我已经准备了以下用于检测句子的正则表达式。它基本上符合我的需求——除了包括评论。

const basicSentence = /(?:^|n| )(?:[^.!?]|[.!?][^ *_~n])+[.!?]/gi;

我还准备了以下用于检测注释的正则表达式。它也如预期的那样工作,至少在我自己的测试中是这样。

const comment = /<!--.*?-->/gi;

示例

为了更好地了解我想要实现的目标,让我们举一个例子。比方说,我有以下一段文字:

foo0 
b<!-- comment -->ar.
foo1 bar?
<!-- comment -->
foo2bar!

(最后还有一行换行符,但我不知道如何在Stackoverflow标记中添加空行。(

预期结果是:

foo0 
b<!-- comment -->ar.<!-- 10 -->
foo1 bar?<!-- 9 -->
<!-- comment -->
foo2bar!<!-- 12 -->

(这一次,末尾还有

no换行符。(

更新:对不起,我已经更正了示例中的预期结果。

.replace传递一个回调,用空字符串替换所有注释,然后返回修剪后的匹配长度:

const input = `foo0 
b<!-- comment -->ar.
foo1 bar?
<!-- comment -->
foo2bar!
`;
const output = input.replace(
/(?:^|n| )(?:[^.!?]|[.!?][^ *_~n])+[.!?]/g,
(match) => {
const matchWithoutComments = match.replace(/<!--.*?-->/g, '');
return `${match}<!-- ${matchWithoutComments.length} -->`;
}
);
console.log(output);

当然,如果您愿意的话,您也可以使用类似的模式来用内部文本内容替换markdown表示法:

.replace(/([*_]{1,2}|~~)((.|n)*?)1/g, '$2')

(由于regex不太擅长使用嵌套且可能不平衡的标记,您可能不得不重复这一行,直到找不到其他替换项为止(

此外,对于每个注释,当前的正则表达式要求每个句子都以.!?结尾。<!--中注释的!被视为(短(句子的结尾。一种选择是查找空白(空格或换行符(或regex:末尾的输入末尾

const input = `foo0 
b<!-- comment -->ar.
foo1 bar?
<!-- comment -->
foo2bar!
<!-- comment -->`;
const output = input.replace(
/(?:^|n| )(?:[^.!?]|[.!?][^ *_~n])+[.!?](?=s|$|[*_~])/g,
(match) => {
const matchWithoutComments = match.replace(/<!--.*?-->/g, '');
return `${match}<!-- ${matchWithoutComments.length} -->`;
}
);
console.log(output);

https://regex101.com/r/RaTIOi/1

最新更新