有没有办法只使用正则表达式进行整数增量替换。
问题是,我的文本文件包含1 000 000行,所有行都以%
开头我想使用正则表达式逐步替换整数#。
input:
% line one
% line two
% line three
...
output:
1 line one
2 line two
3 line three
...
答案 0 :(得分:5)
n = 1
with open('sourcefile.txt') as input:
with open('destination.txt', 'w') as output:
for line in input:
if line.startswith('%'):
line = str(n) + line[1:]
n += 1
output.write(line)
答案 1 :(得分:4)
这是在Python中实现它的方法
import re
from itertools import count
s="""
% line one
% line two
% line three"""
def f():
n=count(1)
def inner(m):
return str(next(n))
return inner
new_s = re.sub("%",f(),s)
或者你可以在那里使用lambda函数:
new_s = re.sub("%",lambda m,n=count(1):str(next(n)),s)
但是完全跳过regexp很容易也更好
from __future__ import print_function # For Python<3
import fileinput
f=fileinput.FileInput("file.txt", inplace=1)
for i,line in enumerate(f):
print ("{0}{1}".format(i, line[1:]), end="")
由于所有行都以“%”开头,因此甚至不需要查看第一个字符
答案 2 :(得分:4)
虽然这个问题最好通过逐行读取文件并使用简单的字符串函数检查第一个字符来解决,但以下是如何在java中对字符串进行增量替换:
Pattern p = Pattern.compile("^%");
Matcher m = p.matcher(text);
StringBuffer sb = new StringBuffer();
int i = 0;
while (m.find()) {
m.appendReplacement(sb, String.valueOf(i++));
}
m.appendTail(sb);
return sb.toString();
答案 3 :(得分:0)
根据您选择的语言(您已经列出了一些),PHP的preg_replace_callback()可能是一个适当的功能
$text = "% First Line\n% Second Line\n% Third Line";
function cb_numbers($matches)
{
static $c = 1;
return $c++;
}
$text = preg_replace_callback(
"/(%)/",
"cb_numbers",
$text);
echo $text;
答案 4 :(得分:0)
在python re.sub中接受函数作为参数参见http://docs.python.org/library/re.html#re.sub
答案 5 :(得分:0)
和PHP版本的好措施:
$input = @fopen('input.txt', 'r');
$output = @fopen("output.txt", "w");
if ($input && $output) {
$i = 0;
while (!feof($input)) {
$line = fgets($input);
fputs($output, ($line[0] === '%') ?
substr_replace($line, ++$i, 0, 1) :
$line
);
}
fclose($input);
fclose($output);
}
只是因为你可以,perl one-liner(是的,带正则表达式):
perl -i.bak -pe 'BEGIN{$i=1} (s/^%/$i/) && $i++' input.txt
答案 6 :(得分:0)
这是一个C#(3.0+)版本:
string s = "% line one\n% line two\n% line three";
int n = 1;
s = Regex.Replace(s, @"(?m)^%", m => { return n++.ToString(); });
Console.WriteLine(s);
输出:
1 line one
2 line two
3 line three
当然它需要将整个文本加载到内存中。如果我真的这样做,我可能会采用逐行方法。
答案 7 :(得分:0)
import re, itertools
counter= itertools.count(1)
replacer= lambda match: "%d" % counter.next()
text= re.sub("(?m)^%", replacer, text)
counter
是......一个柜台:)。 replacer
是一个将计数器值作为字符串返回的函数。 "(?m)^%"
正则表达式适用于行开头的每个%
(请注意多行标记)。