删除单个换行符,保留“空”行

时间:2012-05-05 18:25:43

标签: regex autohotkey

假设我的文字类似于使用光标选择的以下文字:

This is a test. 
This 
is a test.

This is a test. 
This is a 
test.

我想将其转换为:

This is a test. This is a test

This is a test. This is a test

换句话说,我想用空格替换单个换行符,只留空行。

我认为以下内容可行:

RemoveSingleLineBreaks()
{
  ClipSaved := ClipboardAll
  Clipboard =
  send ^c
  Clipboard := RegExReplace(Clipboard, "([^(\R)])(\R)([^(\R)])", "$1$3")    
  send ^v
  Clipboard := ClipSaved
  ClipSaved = 
}

但事实并非如此。如果我将它应用于上面的文本,它会产生:

This is a test. This is a test.
This is a test. This is a test.

也删除了中间的“空行”。这不是我想要的。

澄清:通过空行表示任何带有“白色”字符的行(例如制表符或空格)

有什么想法怎么做?

4 个答案:

答案 0 :(得分:6)

RegExReplace(Clipboard, "([^\r\n])\R(?=[^\r\n])", "$1$2")

假设新行标记末尾包含CRLF(例如CRLF,{{1},则会删除单个换行符},CR+LF)。它不会将空格统计为空。

您的主要问题是使用LF+CR

  字符类中的

\ R只是字母“R” [source]

解决方案是直接使用\RCR字符。


  

澄清:空行是指任何带有“白色”字符的行(例如制表符或空格)

LF

这与上面的相同,但将空格计为空。这是有效的,因为它接受除了换行符之外的所有字符,非贪婪(RegExReplace(Clipboard, "(\S.*?)\R(?=.*?\S)", "$1") )直到换行符后面和前面的第一个非空格字符,因为*?与换行符不匹配默认值。

前瞻用于避免“吃”(匹配)下一个字符,这可能会破坏单字符行。请注意,由于它不匹配,因此不会替换它,我们可以将其从替换字符串中删除。无法使用lookbehind,因为PCRE不支持可变长度的lookbehinds,因此在那里使用正常的捕获组和反向引用。


  

我想用空格替换单个换行符,只留空行。

如果你想用空格替换换行符,这更合适:

.

这将用空格替换单个换行符。


如果你想使用lookbehinds和lookaheads:


剥离单线断路器:

RegExReplace(Clipboard, "(\S.*?)\R(?=.*?\S)", "$1 ")


用空格替换单个换行符:

RegExReplace(Clipboard, "(?<=[^\r\n\t ][^\r\n])\R(?=[^\r\n][^\r\n\t ])", "")

出于某种原因,RegExReplace(Clipboard, "(?<=[^\r\n\t ][^\r\n])\R(?=[^\r\n][^\r\n\t ])", " ") 似乎不适用于外观和前瞻。至少,不是我的测试。

答案 1 :(得分:1)

Clipboard := RegExReplace(Clipboard, "(\S+)\R", "$1 ")

答案 2 :(得分:1)

我相信这会奏效:

text=
(
This is a test. 
This 
is a test.

This is a test. 
This is a 
test.
)
MsgBox %    RegExReplace(text,"\S\K\v(?=\S)",A_Space)

答案 3 :(得分:1)

#SingleInstance force

#v::
    Send ^c
    ClipWait
    ClipSaved = %clipboard%

    Loop
    {
        StringReplace, ClipSaved, ClipSaved, `r`n`r`n, `r`n, UseErrorLevel
        if ErrorLevel = 0  ; No more replacements needed.
            break
    }
    Clipboard := ClipSaved
    return