簡體   English   中英

正則表達式 - 將字符串中的 \\n 和 \n 替換為<br>但不是 \\\\n

[英]Regex - Replace \\n and \n in string by <br> but not \\\\n

我正在嘗試用<br>替換字符串中的所有\\n\n ,但我不希望替換\\\\n

我嘗試使用以下表達式使用否定的lookbehind,但它沒有返回正確的結果,因為所有的"n""\"都被替換了:

import re
string = "this is a sample\\nstring\\\\ncontaining\nall cases\n\\n\n!"
re.sub(r"(?<!\\)([\\n\n]+)", r"<br>", string)
>>'this is a sample<br>stri<br>g<br>co<br>tai<br>i<br>g<br>all cases<br>!'

預計 output

"this is a sample<br>string\\\\ncontaining<br>all cases<br><br><br>!"

這會變魔術:

re.sub(r"(?<!\\)\\n|\n", "<br>", string)

注意:它將替換換行符(“\n”)和轉義換行符(“\n”或r“\n”)。 它不會轉義“\\n”(或 r“\n”)。 “\\\n”(反斜杠 + 新行)變為“\\<br>”。

也許,你真正想要的是:

re.sub(r"(?<!\\)(\\\\)*\\n|\n", "\1<br>", string)

這將替換所有新行和所有轉義的 n (r"\n")。 r"\\n" 不會被替換。 r"\\\n" 再次被替換(轉義的反斜杠 + 轉義的 n)。

您的正則表達式具有匹配\n\n的字符 class [\\n\n] 您的后視邏輯是正確的,您只需要將角色 class 更改為不同的子模式: \\{1,2}n

請參閱此處使用的正則表達式

(?<!\\)\\{1,2}n
  • (?< \\)否定后視確保前面的不是\
  • \\{1,2}匹配\一次或兩次
  • n從字面上匹配

替換: <br>

替代方案: @revo在問題下方的評論中提供的(?<?\\)\\\\ n


代碼中的用法

在這里查看使用中

import re

r = re.compile(r"(?<!\\)\\{1,2}n")
s = r"this is a sample\\nstring\\\\ncontaining\nall cases\n\\n\n!"
print(r.sub("<br>", s, 0))

結果: this is a sample<br>string\\\\ncontaining<br>all cases<br><br><br>

帶有后視功能的正則表達式版本是最短的解決方案:

import re
s = "this is a sample\\nstring\\\\ncontaining\nall cases and one more\\n\nadded"
print(re.sub(r"(?<!\\)\\n|\n", "<br>", s))
## => this is a sample<br>string\\ncontaining<br>all cases and one more<br><br>added

請參閱此 Pyhton 演示

細節

  • (?< \\)\\n - 如果緊挨當前位置的左側有一個\符號,然后是一個\n 2-char 字符串,則匹配失敗
  • \n - LF 符號。

這是一個帶有來自 OP 的字符串的正則表達式演示

另一種方法是匹配並捕獲要保留的\\n ,然后匹配\n和 LF 而不捕獲,並使用 lambda 表達式作為替換參數來實現自定義替換邏輯:

import re
s = "this is a sample\\nstring\\\\ncontaining\nall cases and one more\\n\nadded"
print(re.sub(r"(\\\\n)|\\n|\n", lambda x: r"<br>" if not x.group(1) else x.group(), s))
# => this is a sample<br>string\\ncontaining<br>all cases and one more<br><br>added

請參閱Python 演示

在這里, (\\\\n)|\\n|\n匹配並捕獲\\n(\\\\n) (這將被重新插入到結果中( if not x.group(1) else x.group() = 如果第 1 組匹配,則替換為其內容),或匹配\n (與\\n )或 LF(與\n ),它們將被替換為<br>

也許這會找到你想要的,而不是你可以用<br>替換:
(?<?\\)(\\)n|( < \\)(\\\\)n

上面提到的魔法和代碼行在某些情況下具有相似的輸出,但它沒有在數據集中的選定列表中提供所需的輸出,其中格式在幾次迭代后發生了變化。

暫無
暫無

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

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