簡體   English   中英

正則表達式/JavaScript:拆分字符串以按每行最大字符數分隔行,並向后查找 n 個字符以尋找可能的空格?

[英]Regex / JavaScript: Split string to separate lines by max characters per line with looking n chars backwards for a possible whitespace?

這與How to split a string at every n characters or to near previous space類似,但是,與我根據標題所期望的相反,如果只有一個長詞而沒有任何空格,則該解決方案不起作用.

所以我需要一個正則表達式,它通過每行的最大字符數來分割一個字符串以分隔行(如果需要多次),並向后看n 個字符以尋找可能的空格(如果找到則中斷,否則為最大長度)?

編輯 1:例如,最大行長度為 30 個字符,向后空格查找為 15 個字符:

Loremipsumilydummy text of the印刷和排版行業。

該句子的第一個單詞的長度為 32 個字符。 所以輸出應該是:

Loremipsumissimplydummytextoft  # Line has length of 30 char
he printing and typesetting     # Cut before the word at otherwise 30 char
industry.

所以第一個單詞應該在第 30 個字符之后強制剪切,因為沒有空格。

剩余的字符串在單詞“industry”之前的長度為 28(或帶破折號的 29),因此在第 30 個字符的位置有一個單詞,因此該解決方案在 15 個字符范圍內查找前一個空格。 這條線在“行業”一詞之前被打破。

編輯 2:文本的第二個示例:

Loremipsumilydummy text of the印刷和排版行業。 Loremipsum 只是印刷和排版行業的虛擬文本。 Loremipsumilydummy text of the印刷和排版行業。 Loremipsum 只是印刷和排版行業的虛擬文本。

應該輸出:

Loremipsumissimplydummytextoft
he printing and typesetting
industry. Loremipsumis simply
dummytext ofthe printing and
typesetting industry.
Loremipsumissimplydummytextoft
he printing and typesetting
industry. Loremipsumis simply
dummytext ofthe printing and
typesetting industry.

此正則表達式的用例是將長字符串格式化為可讀文本,強制執行最大行長度,行以字符而不是空格開頭。

可選要求:在最初發布后,我在 Edit 1 中添加了該示例時,我還添加了一個可選要求,即在下一行的開頭添加一個破折號“-”字符,如果一個單詞在最大行長度處被剪切。 我現在將其從示例中刪除,並將其添加為單獨的可選要求。

所以一個可選要求:如果一行在最大長度而不是空格處被打破,那么應該在該行的末尾附加一個破折號(而不是在下一行的開頭,正如我最初描述的那樣)。

Loremipsumissimplydummytextoft-  # Line length 30+1 char with an appended a dash
he printing and typesetting     # Cut before the word at otherwise 30 char
industry.

您可以使用

 var s = "Loremipsumissimplydummytextofthe printing and typesetting industry. Loremipsumis simply dummytext ofthe printing and typesetting industry. Loremipsumissimplydummytextofthe printing and typesetting industry. Loremipsumis simply dummytext ofthe printing and typesetting industry."; var regex = /\\s*(?:(\\S{30})|([\\s\\S]{1,30})(?!\\S))/g; console.log( s.replace(regex, function($0,$1,$2) { return $1 ? $1 + "-\\n" : $2 + "\\n"; } ) )

細節

  • \\s* - 0 個或多個空白字符。
  • (?: - 非捕獲組的開始:
    • (\\S{30}) - 第 1 組(在回調方法中用$1變量引用):三十 ( n ) 個非空白字符
    • | - 或者
    • ([\\s\\S]{1,30})(?!\\S)) - 第 2 組(在回調方法中用$2變量引用):任意一到三十 ( n ) 個字符,盡可能多,但沒有緊跟一個非空白字符。

function($0,$1,$2) { return $1 ? $1 + "-\\n" : $2 + "\\n"; } function($0,$1,$2) { return $1 ? $1 + "-\\n" : $2 + "\\n"; } function($0,$1,$2) { return $1 ? $1 + "-\\n" : $2 + "\\n"; } part 表示如果Group 1 匹配(即我們匹配了一個很長的單詞被切成兩部分),我們將匹配替換為Group 1 value + hyphen 和一個換行符。 否則,如果第 2 組匹配,我們將替換為第 2 組值 + 換行符。

ES6+ 兼容代碼片段

 const text = "Loremipsumissimplydummytextofthe printing and typesetting industry. Loremipsumis simply dummytext ofthe printing and typesetting industry. Loremipsumissimplydummytextofthe printing and typesetting industry. Loremipsumis simply dummytext ofthe printing and typesetting industry."; const lineMaxLen = 30; const wsLookup = 15; // Look backwards n characters for a whitespace const regex = new RegExp(String.raw`\\s*(?:(\\S{${lineMaxLen}})|([\\s\\S]{${lineMaxLen - wsLookup},${lineMaxLen}})(?!\\S))`, 'g'); console.log( text.replace(regex, (_, x, y) => x ? `${x}-\\n` : `${y}\\n`) );

最終答案:

(\\S[\\s\\S]{1,30}$|\\S[\\s\\S]{1,29}(?:\\s+)|\\S{30})

進化:

  1. ([\\s\\S]{1,15}(?!\\S)|\\S{15,})

您只需要通過添加額外要求的“或”語句修改鏈接中的答案:|\\S{15,}

  1. 響應您的編輯,這是我修改后的正則表達式:([\\s\\S]{1,15}(?!\\S)|\\S{15})

您可以用 30 或您選擇的字符截斷值替換 15s

  1. 調整您的進一步澄清: (\\S[\\s\\S]{1,14}(?:\\s*)|\\S{15})

現在字符串必須以非空格開頭,它匹配但不會在前 15 個字符之后捕獲額外的空格。 同樣,您需要將 15 和 14 更改為您想要的長度。

  1. (\\S[\\s\\S]{1,30}$|\\S[\\s\\S]{1,29}(?:\\s+)|\\S{30}) 在多個'或' 語句,如果字符串以非空白字符結尾,則捕獲字符串的結尾。 如果它以空格字符結尾,則 'or' 語句的第二部分將捕獲它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM