我需要帮助构建一个正则表达式,可以从纯文本文件中删除偶数行。
给定以下输入:
line1
line2
line3
line4
line5
line6
它将输出以下内容:
line1
line3
line5
谢谢!
我需要帮助构建一个正则表达式,可以从纯文本文件中删除偶数行。
给定以下输入:
line1
line2
line3
line4
line5
line6
它将输出以下内容:
line1
line3
line5
谢谢!
$ awk 'NR%2==1' file
line1
line3
line5
偶数行:
$ awk 'NR%2==0' file
line2
line4
line6
好的,如果你在搜索和替换所有匹配项时
^(.*)\r?\n.*
在“^
匹配行首模式”和“.
不匹配换行符模式”的情况下进行替换。
\1
那么你会丢失每一行的偶数行。
例如,在C#中:
resultString = Regex.Replace(subjectString, @"^(.*)\r?\n.*", "$1", RegexOptions.Multiline);
result = re.sub(r"(?m)^(.*)\r?\n.*", r"\1", subject)
首先,我完全同意这不是正则表达式应该做的事情的共识。
以下是Java演示:
public class Test {
public static String voodoo(String lines) {
return lines.replaceAll("\\G(.*\r?\n).*(?:\r?\n|$)", "$1");
}
public static void main(String[] args) {
System.out.println("a)\n"+voodoo("1\n2\n3\n4\n5\n6"));
System.out.println("b)\n"+voodoo("1\r\n2\n3\r\n4\n5\n6\n7"));
System.out.println("c)\n"+voodoo("1"));
}
}
输出:
a)
1
3
5
b)
1
3
5
7
c)
1
正则表达式的简要解释:
\G # match the end of the previous match
( # start capture group 1
.* # match any character except line breaks and repeat it zero or more times
\r? # match the character '\r' and match it once or none at all
\n # match the character '\n'
) # end capture group 1
.* # match any character except line breaks and repeat it zero or more times
(?: # start non-capture group 1
\r? # match the character '\r' and match it once or none at all
\n # match the character '\n'
| # OR
$ # match the end of the input
) # end non-capture group 1
\G
从字符串的开头开始。每对行(第二行是可选的,以防最后不均匀的行)都会用该对中的第一行替换。
但再次强调:使用普通编程语言(如果可以称之为“正常”:)是正确的方法。
编辑
正如Tim所建议的那样,这也可以工作:
replaceAll("(?m)^(.*)\r?\n.*", "$1")
String result = subject.replaceAll("(?m)^(.*)\r?\n.*", "$1");
不应该也能起到同样的作用吗?在匹配之后,正则表达式引擎会自动到达下一行的开头。 - Tim Pietzcker我在Sublime Text的“正则表达式查找替换”模式下使用捕获组(.*) --> $1,以删除每隔一行的换行符,并在值之间放置一个制表符。
replace (.*)\n(.*)\n
with $1\t$2\n
replace (.*)\n(.*)\n
with $1\n
这个程序将从文本文件中删除偶数行:
grep '[13579]$' textfile > textfilewithoddlines
并输出以下内容:
行1
行3
行5
$
)决定,该数字必须是以下5个数字之一。 - bartsed -n '2,$n;p' textfile
可能更适合。 - emil