首先是一些反馈,顺便称赞一下你在十分钟内写出这个正则表达式:
-
(?<=\p{L}) => 这很好,但我建议将“字母”包含在实际捕获中,这样用户就能看到正则表达式在哪里发现了潜在的“句子结尾”。称赞你同时考虑了大写字母和小写字母。因此,在我的建议中,我将 ?<= 替换为 ?:
-
(?<!\\[\w+]) => 我认为,为了达到你避免某些标记产生误报的意图,这部分必须位于你的“字母”左侧。此外,+ 应该放在方括号外面,因为许多标记包含多个字符,例如 \s1。
-
某些标记包含 *,例如表示某物结束的 \em*。我隐约记得某些标记可以甚至必须包含 +。如果是这种情况,你可以轻松地在字符列表中添加这些字符,例如 [\w*+]。
-
\s*(?:\\\w+)?\s* => 我将这一部分替换为“跳过任意数量的潜在标记以及节末尾和下一节开头之间的任意空白字符”。
-
\\v [\d\w]+ \p{Lu} => 查找后跟大写字母的节。看来你对 \v 和节号之间以及节号之后的“经典空格”很有信心,所以我保留了该语法。
我想提交一个修改后的正则表达式,不声称它是最终解决方案,只是希望覆盖更多情况:
(?<!\\[\w\*]*)(?:\p{L})\s*(?:\\[\w\*]+\s+)*\\v [\d\w]+ \p{Lu}
以下是我的正则表达式说明,来自我的工具:
(?<!\\[\w\*]*)(?:\p{L})\s*(?:\\[\w\*]+\s+)*\\v [\d\w]+ \p{Lu}
(?<!\\[\w\*]*)(?:\p{L})\s*(?:\\[\w\*]+\s+)*\\v [\d\w]+ \p{Lu}
(?<!\\[\w\*]*)(?:\p{L})\s*(?:\\[\w\*]+\s+)*\\v [\d\w]+ \p{Lu}选项:不区分大小写;精确空格;点号匹配换行符
-
断言在此位置不可能反向匹配下方的正则表达式(负向后行断言)
- 匹配反斜杠字符
-
匹配下方列表中存在的单个字符
- “单词字符”(Unicode;任何字母或表意文字、数字、字母数字、连接标点)
- 字面字符“*”
-
匹配下方的正则表达式
- 匹配 Unicode 类别“字母”中的字符(任何语言的任何类型字母)
-
匹配单个“空白字符”(任何 Unicode 分隔符、制表符、换行符、回车符、垂直制表符、换页符、下一行、零宽空格)
-
匹配下方的正则表达式
- 匹配反斜杠字符
-
匹配下方列表中存在的单个字符
- “单词字符”(Unicode;任何字母或表意文字、数字、字母数字、连接标点)
- 字面字符“*”
-
匹配单个“空白字符”(任何 Unicode 分隔符、制表符、换行符、回车符、垂直制表符、换页符、下一行、零宽空格)
- 匹配反斜杠字符
- 字面匹配字符串“v ”(不区分大小写)
-
匹配下方列表中存在的单个字符
- “数字”(任何 Unicode 脚本中的任何十进制数)
- “单词字符”(Unicode;任何字母或表意文字、数字、字母数字、连接标点)
- 字面匹配字符“ ”
- 匹配 Unicode 类别“大写字母”中的字符(具有小写变体的大写字母)
这里是一些我用于测试的示例文本。很可能不完整(在每个示例末尾,我标记了它是捕获项还是非捕获项):
\v 8 Some text without \em punctuation\em* \rem \any \v 9 A new verse which is a new sentence, starting with a capital. [catch]
\v 8 Some text without \em punctuation\em* \v 9 A new verse which is a new sentence, starting with a capital. [catch]
\v 8 Some text without punctuation \v 9a A new verse which is a new sentence, starting with a capital. [catch]
\v 8 Some text with proper \em punctuation.\em* \just \one \more \v 9 A new verse which is a new sentence, starting with a capital. [punctuation present, so no catch]
\v 8 Some text ending an an all-cap word like \em LORD\em* \v 9 A new verse which is a new sentence, starting with a capital. [catch]
\v 10 A long sentence \whatever \v 11a over two verses or more. [No punctuation needed, so no catch]
所以,这很有趣。希望我没有偏离太远。遗憾的是,我从来记不住 PT 使用哪种正则表达式风味。如果因为风味不同导致语法问题,我可以轻松应用另一种风味,如 .NET 或 Java,并重新运行我的工具。
再次说明:这不是解决方案,但也许有助于开启对话。
希望有帮助
First some feedback, with compliments for writing that in ten minutes:
-
(?<=\p{L}) => Is good, but I propose to include “the letter” in the actual catch, so that the user will see where the regex spotted a potential “end of sentence”. Compliments for catching upper case and lower case letters. So I replace ?<= with ?: in my proposal.
-
(?<!\\[\w+]) => I believe for your intension to avoid false positives with some marker, this part has to be to the left of your “letter”. Also the + should be outside the square brackets as many markers have multiple characters like \s1.
-
And certain markers include the *, for example end-of-something like \em*. I vaguely remember that certain markers can or must even include +. If that is the case, you can easily add to the list of characters like [\w*+].
-
\s*(?:\\\w+)?\s* => This one I replace with "skip over any number of potential markers and any whitespace between the end of the verse and the start of the next verse.
-
\\v [\d\w]+ \p{Lu} => Find a verse followed by an upper-case letter. Seems you are confident here about a “classic space” between \v and the verse number and after the verse number, so I kept that syntax.
I would like to submit a modified regex, not claiming it is the final solution, just hopefully covering more cases:
(?<!\\[\w\*]*)(?:\p{L})\s*(?:\\[\w\*]+\s+)*\\v [\d\w]+ \p{Lu}
Here is the blurb for my regex, as per my tool:
(?<!\\[\w\*]*)(?:\p{L})\s*(?:\\[\w\*]+\s+)*\\v [\d\w]+ \p{Lu}
(?<!\\[\w\*]*)(?:\p{L})\s*(?:\\[\w\*]+\s+)*\\v [\d\w]+ \p{Lu}
(?<!\\[\w\*]*)(?:\p{L})\s*(?:\\[\w\*]+\s+)*\\v [\d\w]+ \p{Lu}Options: Case insensitive; Exact spacing; Dot matches line breaks
-
Assert that it is impossible to match the regex below backwards at this position (negative lookbehind)
- Match the backslash character
-
Match a single character present in the list below
- Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
- A “word character” (Unicode; any letter or ideograph, digit, letter number, connector punctuation)
- The literal character “*”
-
Match the regular expression below
- Match a character from the Unicode category “letter” (any kind of letter from any language)
-
Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line, zero-width space)
- Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
-
Match the regular expression below
- Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
- Match the backslash character
-
Match a single character present in the list below
- Between one and unlimited times, as many times as possible, giving back as needed (greedy)
- A “word character” (Unicode; any letter or ideograph, digit, letter number, connector punctuation)
- The literal character “*”
-
Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line, zero-width space)
- Between one and unlimited times, as many times as possible, giving back as needed (greedy)
- Match the backslash character
- Match the character string “v ” literally (case insensitive)
-
Match a single character present in the list below
- Between one and unlimited times, as many times as possible, giving back as needed (greedy)
- A “digit” (any decimal number in any Unicode script)
- A “word character” (Unicode; any letter or ideograph, digit, letter number, connector punctuation)
- Match the character “ ” literally
- Match a character from the Unicode category “uppercase letter” (an uppercase letter that has a lowercase variant)
And here is some sample text, that I used for testing. Most likely incomplete (at the end of each example, I mark, whether it is a catch or not):
\v 8 Some text without \em punctuation\em* \rem \any \v 9 A new verse which is a new sentence, starting with a capital. [catch]
\v 8 Some text without \em punctuation\em* \v 9 A new verse which is a new sentence, starting with a capital. [catch]
\v 8 Some text without punctuation \v 9a A new verse which is a new sentence, starting with a capital. [catch]
\v 8 Some text with proper \em punctuation.\em* \just \one \more \v 9 A new verse which is a new sentence, starting with a capital. [punctuation present, so no catch]
\v 8 Some text ending an an all-cap word like \em LORD\em* \v 9 A new verse which is a new sentence, starting with a capital. [catch]
\v 10 A long sentence \whatever \v 11a over two verses or more. [No punctuation needed, so no catch]
So, this was fun. Hope I am not too far off. I can sadly never remember what regex-flavour PT uses. If there are issues with syntax because of flavours, I could easily apply a different one like .NET or Java and re-run my tool.
Again: Not the solution but maybe useful to get a dialog going.
hth
机器翻译自 English