正则表达式捕获带引号的句子
REGEX to capture sentences with quotes
我在组合正则表达式来匹配引号和句子时遇到问题。以下是我试图满足的(简化的)规格:
一个句子是一串字符后跟一个标点符号(一个点,为简单起见)或一个换行符。
引号是两个 "
.
之间的字符链
每个句子都应该是一个新的匹配项。
一句话可以包含引号,引号可以包含句子。只有引用中的最后一句话才能结束捕获。
到目前为止我已经想出了这个:\s*((?:("[^"]*")|[^.\n])*\.+"?)\s*
测试用例:REGEX101
如您所见,我无法正确地将引号与句子分开。例如:
§2:"Your lordship," Mya informed Lord Robert, "Lady Waynwood’s banners have been seen an hour down the road. She will be here soon, with your cousin Harry. Will you want to greet them"
应该是完全匹配,但正则表达式给了我三个并捕获了下一段。
§3:"They were invited," she said uncertainly, "for the tourney. I don’t..."
应该作为完全匹配停止,但正则表达式继续捕获 Alayne closed her book.
我不知道出了什么问题,非常感谢任何帮助。
用一个简单的正则表达式,你想做的事情是极其困难甚至不可能的。最好编写一个解析器,因为在给定的情况下这会容易得多。
您需要做的是:
- 您需要两种模式:"within quotation marks" 或 "outside of quotation marks"
- 从 "outside of quotation marks"
开始
- 如果遇到引号,请在模式之间切换
- 如果您在"outside of quotation marks"-模式中遇到标点符号,请在此处中断匹配并开始新的匹配
- 如果您在 "within quotation marks" 模式中遇到标点符号,请检查下一个字符是否为引号。如果是,则在此处中断匹配,开始新的匹配并将模式设置为 "outside of quotation marks"
这应该能满足您的需求。
((?![.\n\s])[^.\n"]*(?:"[^\n"]*[^\n".]"[^.\n"]*)*(?:"[^"\n]+\."|\.|(?=\n)))
拆分:
(?![.\n\s])
- 首先检查我们以有效字符开始(不是空格或句子结尾。
[^.\n"]*
- 然后匹配任何不包含在引号中且不包含句子终止符的文本。
(?:"[^\n"]*[^\n".]"[^.\n"]*)
- 然后匹配(在非捕获组中)包含至少一个字符且不包含换行符且不以句子结束符结尾的引用 - 后跟零 -或多个不在引号中且不包含句子终止符的字符。
*
- 前面的非捕获组可以重复零次(这样可以有不带引号的句子)-或-更多次。
(?:"[^"\n]+\."|\.|(?=\n))
- 最后,在句子末尾添加以句号结尾的引号或句号,或者检查我们是否以换行符结尾。
我在组合正则表达式来匹配引号和句子时遇到问题。以下是我试图满足的(简化的)规格:
一个句子是一串字符后跟一个标点符号(一个点,为简单起见)或一个换行符。
引号是两个
"
. 之间的字符链
每个句子都应该是一个新的匹配项。
一句话可以包含引号,引号可以包含句子。只有引用中的最后一句话才能结束捕获。
到目前为止我已经想出了这个:\s*((?:("[^"]*")|[^.\n])*\.+"?)\s*
测试用例:REGEX101
如您所见,我无法正确地将引号与句子分开。例如:
§2:"Your lordship," Mya informed Lord Robert, "Lady Waynwood’s banners have been seen an hour down the road. She will be here soon, with your cousin Harry. Will you want to greet them"
应该是完全匹配,但正则表达式给了我三个并捕获了下一段。
§3:"They were invited," she said uncertainly, "for the tourney. I don’t..."
应该作为完全匹配停止,但正则表达式继续捕获 Alayne closed her book.
我不知道出了什么问题,非常感谢任何帮助。
用一个简单的正则表达式,你想做的事情是极其困难甚至不可能的。最好编写一个解析器,因为在给定的情况下这会容易得多。
您需要做的是:
- 您需要两种模式:"within quotation marks" 或 "outside of quotation marks"
- 从 "outside of quotation marks" 开始
- 如果遇到引号,请在模式之间切换
- 如果您在"outside of quotation marks"-模式中遇到标点符号,请在此处中断匹配并开始新的匹配
- 如果您在 "within quotation marks" 模式中遇到标点符号,请检查下一个字符是否为引号。如果是,则在此处中断匹配,开始新的匹配并将模式设置为 "outside of quotation marks"
这应该能满足您的需求。
((?![.\n\s])[^.\n"]*(?:"[^\n"]*[^\n".]"[^.\n"]*)*(?:"[^"\n]+\."|\.|(?=\n)))
拆分:
(?![.\n\s])
- 首先检查我们以有效字符开始(不是空格或句子结尾。[^.\n"]*
- 然后匹配任何不包含在引号中且不包含句子终止符的文本。(?:"[^\n"]*[^\n".]"[^.\n"]*)
- 然后匹配(在非捕获组中)包含至少一个字符且不包含换行符且不以句子结束符结尾的引用 - 后跟零 -或多个不在引号中且不包含句子终止符的字符。*
- 前面的非捕获组可以重复零次(这样可以有不带引号的句子)-或-更多次。(?:"[^"\n]+\."|\.|(?=\n))
- 最后,在句子末尾添加以句号结尾的引号或句号,或者检查我们是否以换行符结尾。