我有一个由不使用文本限定符的人以管道作为分隔符导出的分隔文件,并且文本包含管道字符。应该有 13 列。
已在多行中创建了附加列。有些是 3 个,有些是 4 个。因此,创建的附加列的数量不同。
分隔符一直到第 10 个管道之后的文本/列以及最后两个管道之后的文本/列为止。我想使用正则表达式模式一次性替换第 10 个管道之后和最后两个管道之前的额外管道字符,无论它是 1 个还是多个管道。
我试过这个:
^([^|]*)(?!(?:\|[^|\r\n]*){12}$)((?:\|[^|\r\n]*){10})(?:(\|)([^|\r\n]*))((?:\|[^|\r\n]*){2})$
替换为
$1$2$4$5
。
这只适用于有 14 列的情况。列数较多的行不匹配。
这是超过 14 列的行:
5070599047|SA|03/31/2023 00:00:00|04/03/2023 00:00:00|23121|152|65642.950000|0|0|XP-OFS-222761665|ZIB|BRH|NPAU|31-03-2023|749542|30271246.390000|342
我需要的结果:
5070599047|SA|03/31/2023 00:00:00|04/03/2023 00:00:00|23121|152|65642.950000|0|0|XP-OFS-222761665|ZIB BRH NPAU 31-03-2023 749542|30271246.390000|342
我需要删除 ZIB 之后和
|30271246.390000|342
之前的所有管道,并将文本保留在该空间中。我还需要一种适用于超过 13 列的行的模式,无论额外的列数如何,将它们全部减少到 13 列。
前10根和最后2根管子要保留。其他每一个都将被替换为一个空格。如果字符串至少包含 13 个竖线 (
10+2+1
),则以下正则表达式的每个匹配都可以用空格替换。这会导致至少有一个管道被匹配(并因此转换为空格)。
^(?:[^|]*\|){10}[^|]*\K\||[^|]*\K\|(?=.*(?:\|[^|]*){2}$)
一般来说,如果要保留第一个
n
和最后一个 m
管道,则必须至少有 n + m + 1
管道才能工作。
请注意,Notepad++ 使用 Boost 正则表达式引擎,它与“演示”链接中使用的PCRE 引擎 略有不同。特别是,两者都支持
\K
,这会导致先前匹配的标记从返回的匹配中被丢弃,并将匹配的开头重置为字符串中的当前位置。
表达式可以分解如下。1
^ # match the beginning of the string
(?: # begin a non-capture group
[^|]*\| # match >= 0 characters other than '|', then '|'
) # end the non-capture group
{10} # execute preceding non-capture group 10 times
[^|]* # match >= 0 characters other than '|'
\K # discard previously-consumed tokens and reset start of match
\| # match '|'
| # or
[^|]* # match >= 0 characters other than '|'
\K # discard previously-consumed tokens and reset start of match
\| # match '|'
(?= # begin the positive lookahead
.* # match >= 0 characters other than line terminators
(?: # begin a non-capture group
\|[^|]* # match '|' then >= 0 characters other than '|'
) # end the non-capture group
{2} # execute preceding non-capture group twice
$ # match the end of the string
) # end the positive lookahead
1 此外,通过将鼠标悬停在链接处表达式的每个部分(光标,而不是您,您自己)上,可以获得其功能的解释。