"0000-22N-06W-01"
"0000-22N-06W-02"
"0000-22N-06W-03"
"0000-22N-06W-04"
import re
output = open("output.txt","w")
input = open("input.txt")
for line in input:
output.write(re.sub(r'^(.{4})-(.{3})-(.{3})-(.{2})$', r'\1-\4-\2-\3', line))
input.close()
output.close()
NOTE: If you actually have " in your data then you should change your regular expression to this one:
^"(.{4})-(.{4})-(.{3})-(.{3})"$
Regex101 Demo
Answer from Ibrahim Najjar on Stack Overflow"0000-22N-06W-01"
"0000-22N-06W-02"
"0000-22N-06W-03"
"0000-22N-06W-04"
import re
output = open("output.txt","w")
input = open("input.txt")
for line in input:
output.write(re.sub(r'^(.{4})-(.{3})-(.{3})-(.{2})$', r'\1-\4-\2-\3', line))
input.close()
output.close()
NOTE: If you actually have " in your data then you should change your regular expression to this one:
^"(.{4})-(.{4})-(.{3})-(.{3})"$
Regex101 Demo
If you still want to use .read(), try this:
import re
output = open("output.txt","w")
input = open("input.txt").read()
output.write(re.sub(r'^(.{4})(.{4})(.{4})(.{3})$',
r'\1\4\2\3',
input,
flags=re.M))
output.close()
How to edit a text file by using regex (the "sub" function in particular)?
linux - Python re.sub specific syntax - Stack Overflow
Use of re.sub for renaming files/strings not working
python - re.sub - File path - Stack Overflow
f = open('greeneggs', 'w')
f.write('i am Sam\nSam i am\nThat Sam-i-am!\nThat Sam-i-am!\ni do not like that Sam-i-am!')
f.close()
import re
with open('greeneggs', 'r+') as text:
redacted_text = re.sub('i', 'I', text)
text.write(redacted_text)I'm trying to replace the lowercase 'i' in each line with uppercase 'I'. It's supposed to be a simple task but I cannot make it work.
I intentionally use a sample of the original "green eggs" because I want to test how it works before adding the whole wall of text. Also, please advice me how to write a lot of text on a txt file by using Python.
use "r" more to read file, "w" mode will create empty file for writing. .readline() will get and pass the string to the re.sub(). r" .*" will return a string you want to replace after the 'space' character. i assume 'hi 873840' is the only text in your file and your desired output is only 'hi 90'
echo "hi 873840" > hi.txt
python3.6
import re
fp = open("hi.txt", "r")
print(re.sub(r" .*", " 90", fp.readline()))
You should open the file in read mode. re.sub expects three arguments, pattern, repl, string. The problem is the third argument you are passing is a file pointer.
Eg:
import re
with open('/home/hi', 'r', encoding='utf-8') as infile:
for line in infile:
print(re.sub(r"hi+", "hi 90", line.strip()))
Fixing the regex:
>>> pattern = re.compile(r'\.CSV', re.IGNORECASE)
>>> pattern.sub(repl='.xlsx', string='test.CSV')
'test.xlsx'
>>> pattern.sub(repl='.xlsx', string='test.csv')
'test.xlsx'
Not using regex in the first place:
base, ext = os.path.splitext(fname)
if ext.lower() == '.csv':
fname = base + '.xlsx'
If you're compiling a pattern, the first argument to re.compile has to be the pattern to replace. In your case, it should've been \.csv. However, for this specific case, I don't see any benefit in pre-compiling unless you use the same pattern multiple times.
So, using the top-level re.sub function should be sufficient:
>>> re.sub(r'\.csv', r'\.xlsx', 'test.CSV', flags=re.I)
'test\\.xlsx'
If not, compile and use the pattern like this:
>>> p = re.compile(r'\.csv', flags=re.I)
>>> p.sub(r'\.xslx', 'test.CSV')
'test\\.xslx'
I have a very large file for which I need to do some regex that are multiline and re.DOTALL.
Since I do not know the size of a match a priori, I can't read the file line-by-line (or even with some windowed line as I attempted originally).
It turns out for finding regex matches, mmap should work well in theory (I actually havenโt tested it on the large file yet).
So here is the real question: while I can use mmap to read me file, if I use re.sub it returns a string! No bueรฑo! Is there a way to do re.sub without loading the file into memory?
Any suggestions?
As an aside, my other thought was that I could make a limitation that be matched block be less than, say 4kb. Then I could read the file in 4k blocks and apply a search with a window of 8k. That works well for searching the file (and I actually like this more since I am not relying on mmap being efficient). But, again for replacement, it becomes increasingly difficult since I need to know if a substitution happened across the blocks to write it. Then I started to think of ways to detect if there is a gap over my blocks (edit: match between blocks of data). It got really complicated really quickly. I am not giving up on this approach, but I wanted to solicit feedback before I keep working on it
The other issue with this approach is that if I read the file by bytes and then decode it, a more-than-one-byte character can be spliced.
EDIT: I should clarify, but I probably could read the whole file into memory but I think this is also an interesting challenge!
You could try this:
>>> import re
>>> text = 'file1 file2 file3'
>>> x = re.sub(r'file([1-9])',r'file0\1',text)
'file01 file02 file03'
The brackets wrapped around the [1-9] captures the match, and it is the first match. You will see I used it in the replace using \1 meaning the first catch in the match.
Also, if you don't want to add the zero for files with 2 digits or more, you could add [^\d] in the regexp:
x = re.sub(r'file(1-9)',r'file0\1',text)
A bit more of a generic solution now that I'm revisiting this answer using str.format() and a lambda expression:
import re
fmt = '{:03d}' # Let's say we want 3 digits with leading zeroes
s = 'file1 file2 file3 text40'
result = re.sub(r"([A-Za-z_]+)([0-9]+)", \
lambda x: x.group(1) + fmt.format(int(x.group(2))), \
s)
print(result)
# 'file001 file002 file003 text040'
A bit of details about the lambda expression:
lambda x: x.group(1) + fmt.format(int(x.group(2)))
# ^--------^ ^-^ ^-------------^
# filename format file number ([0-9]+) converted to int
# ([A-Za-z_]+) so format() can work with our format
I am using the expression [A-Za-z_]+ assuming the filename contains letters and underscores only besides the training digits. Do pick a more appropriate expression if required.
To match files with single digit on the end, use a word boundary \b:
>>> text = ' '.join('file{}'.format(i) for i in range(12))
>>> text
'file0 file1 file2 file3 file4 file5 file6 file7 file8 file9 file10 file11'
>>> import re
>>> re.sub(r'file(\d)\b',r'file0\1',text)
'file00 file01 file02 file03 file04 file05 file06 file07 file08 file09 file10 file11'