正则表达式删除最后一个换行符



给定以下;分隔字符串


a;; z
toy;d;hh 
toy
;b;;jj
z;
d;23
d;23td
;;io;
b y;b;12
z
a;b;bb;;;34
z

和这个正则表达式

^(?!(?:(a|d))(?:;|$)).*(s*z|$)R*

我希望获得第 1 列不是ad的完整行,并删除匹配的行,以便在替换为空后获得此

a;; z
d;23
d;23td
a;b;bb;;;34

请看演示

在替换面板中,有第 5 个空行,需要删除。

我过去曾为此目的使用过这种s*z。正如这里实现的那样,它似乎不起作用。

任何帮助不胜感激

我认为您的正则表达式不会删除最后一个换行符的原因是它是您要保留的最后一部分末尾的一部分,因此如果不匹配它,您将无法删除它。

所以我重写了正则表达式以匹配您想要保留的行,但也包括匹配项上方和下方的所有内容,而不是其他匹配项。

主要区别在于使用条件仅匹配要保留的组的换行符(如果后跟另一个匹配项)。

正则表达式(换行符以提高可读性):

((?!(a|d)).*(s*z|$)R*)*
(^(a|d).*(?(?=R*(.*s*R+)*(a|b))R))
((?!(a|d)).*(s*z|$)R*)*

替换为$4-->

a;; z
d;23
d;23td
a;b;bb;;;34

为了可读性,我删除了一些非捕获和字符串分隔符逻辑,如有必要,您可以重新添加它们。

零件的逻辑分解:

(?(?=R*(.*s*R+)*(a|b))R)是条件的,则它仅匹配换行符R,如果(?)它后跟(?=)任何以换行符结尾的不匹配行(.*s*R+)*,后跟(a|b)

包含此内容的中间部分(^(a|d).*(?(?=R*(.*s*R+)*(a|b))R))最终成为替换组$4。因此它匹配以(a|d)开头的行,并且除了最后一个匹配之外,所有匹配项也匹配其行尾的换行符。

正则表达式((?!(a|d)).*(s*z|$)R*)*的开头和结尾完全相同,并且匹配所有不需要的内容,以便将其删除。

您可以匹配要删除的内容,并在组中捕获要保留的内容。

为了防止删除捕获组之间的换行符序列,您可以使用 if 子句(?仅在没有更多以[ad];开头的行后跟时匹配 0+ unicode 换行符序列

在替换使用组中 1$1

^(?:(?![ad];).*R*)*|^([ad];.*(?:R[ad];.*)*)(?(?![sS]*R[ad];)R*)

解释

  • ^行首
  • (?:非捕获组
    • (?![ad];)如果行不以 a 或 d 开头,后跟 ;
    • .*R*匹配整行和 0+ 乘以 unicode 换行符序列
  • )*关闭组并重复 0+ 次以匹配所有连续行
  • |
  • ^行首
  • (捕获组 1
    • [ad];.*匹配 a 或 d,后跟 ; 和行的其余部分
    • (?:非捕获组
      • R[ad];.*匹配换行符,a 或 d 后跟 ; 和行的其余部分
    • )*关闭组并重复 0+ 次以匹配所有连续行
  • )关闭组 1
  • (?If 子句,仅当[ad];模式不再出现时,才匹配 unicode 换行符序列
    • (?!消极的展望,断言以下不是
      • [sS]*R[ad];匹配[ad];模式
    • )近距离展望。
    • R*如果断言为真,则匹配 0+ Unicode 换行符序列
  • )关闭如果子句

    查看正则表达式演示

最新更新