首先是一些反饋,並對你在十分鐘內寫出這段代碼表示讚賞:
(?<=\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} 選項:不區分大小寫;精確間距;點號匹配換行符
斷言在此位置反向匹配下方的正則表達式是不可能的(負向前瞻/negative lookbehind)
匹配反斜杠字符
匹配下列列表中存在的單個字符
一個「單詞字符」(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 使用的是哪種正則表達式方言(flavour)。如果因為方言不同而導致語法問題,我可以輕鬆地應用另一種方言(如 .NET 或 Java)並重新運行我的工具。
再次強調:這不是解決方案 ,但或許有助於開啟對話。
希望對你有幫助(hth)
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 顯示原文