2010-07-06 148 views
1

有沒有什麼辦法只用正則表達式進行整數增量替換。正則表達式 - 增量替換

這是問題所在,我有一個包含1條000 000線都開始%

我想有逐步使用正則表達式的整數替換#文本文件。

input: 

% line one 

% line two 

% line three 

... 

output: 

1 line one 

2 line two 

3 line three 

... 
+8

你爲什麼只想用一個正則表達式呢? – Mike 2010-07-06 11:11:45

+0

爲什麼人們總是認爲,一個好的正則表達式可以解決任何問題?對我來說,他們是醜陋的地獄,我希望,我永遠不必保持一個...只是看看這一個:http://stackoverflow.com/questions/1732348/regex-match-open-tags-except- xhtml-self-contained-tags/3180176#3180176 - 這是黑色的藝術。 – 2010-07-06 11:18:04

+0

否 - 正則表達式不會「替換全部」,因此甚至不是增量替換 – 2010-07-06 11:23:41

回答

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) 
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

這裏有一個辦法做到這一點在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) 

ALTER本身你可以在那裏使用lambda功能,像這樣:

new_s = re.sub("%",lambda m,n=count(1):str(next(n)),s) 

但它很容易,更好地跳過的正則表達式完全

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="") 

由於所有的線用「%」就沒有必要甚至看那個第一個字符

+0

+1不使用正則表達式! – 2010-07-06 11:20:18

+0

@Andreas_D:呵呵,他用正則表達式。 – nosklo 2010-07-06 11:23:52

+0

@nosklo ...是啊,okaaay,在這種情況下,「%」也是一個正則表達式... – 2010-07-06 11:30:43

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的一行(是的,用正則表達式):

perl -i.bak -pe 'BEGIN{$i=1} (s/^%/$i/) && $i++' input.txt 
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(); 
+0

你可能想++ 1,而不是1 ++ 。行號通常爲1。 – 2010-07-06 12:29:58

+0

...或將'i'初始化爲1而不是零。 – 2010-07-06 19:44:28

+0

這是我需要的答案,正則表達式的答案。 – dlamblin 2011-11-07 19:09:00

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 

當然它需要被加載到存儲器中的整個文本。如果我真的這樣做,我可能會採用逐行方法。

0
import re, itertools 
counter= itertools.count(1) 
replacer= lambda match: "%d" % counter.next() 
text= re.sub("(?m)^%", replacer, text) 

counter是......計數器:)。 replacer是一個將計數器值作爲字符串返回的函數。 "(?m)^%"正則表達式對於行的開始處的每個%都是正確的(注意多行標誌)。