简体   繁体   English

Ruby正则表达式在文本文件中添加一行

[英]Ruby regex gsub a line in a text file

I need to match a line in an inputted text file string and wrap that captured line with a character for example. 我需要匹配输入的文本文件字符串中的一行,并将该捕获的行包裹在一个字符中。

For example imagine a text file as such: 例如,想象一个文本文件:

test
foo
test
bar

I would like to use gsub to output: 我想用gsub输出:

XtestX
XfooX
XtestX
XbarX

I'm having trouble matching a line though. 我在匹配线路时遇到了麻烦。 I've tried using regex starting with ^ and ending with $, but it doesn't seem to work. 我已经尝试使用正则表达式从^开始并以$结尾,但它似乎不起作用。 Any ideas? 有任何想法吗?

I have a text file that has the following in it: 我有一个文本文件,其中包含以下内容:

test
foo
test
bag

The text file is being read in as a command line argument. 正在将文本文件作为命令行参数读入。

So I got 所以我得到了

string = IO.read(ARGV[0])
string = string.gsub(/^(test)$/,'X\1X')

puts string

It outputs the exact same thing that is in the text file. 它输出与文本文件完全相同的内容。

If you're trying to match every line, then 如果你想匹配每一行,那么

gsub(/^.*$/, 'X\&X')

does the trick. 诀窍。 If you only want to match certain lines, then replace .* with whatever you need. 如果您只想匹配某些行,则将.*替换为您需要的任何内容。

Update: 更新:

Replacing your gsub with mine: 用我的替换你的gsub

string = IO.read(ARGV[0])
string = string.gsub(/^.*$/, 'X\&X')
puts string

I get: 我明白了:

$ gsub.rb testfile
XtestX
XfooX
XtestX
XbarX

Update 2: 更新2:

As per @CodeGnome, you might try adding chomp : 根据@CodeGnome,您可以尝试添加chomp

IO.readlines(ARGV[0]).each do |line|
  puts "X#{line.chomp}X"
end

This works equally well for me. 这对我来说同样适用。 My understanding of ^ and $ in regular expressions was that chomping wouldn't be necessary, but maybe I'm wrong. 我对正则表达式中的^$理解是没有必要进行咀嚼,但也许我错了。

You can do it in one line like this: 你可以在一行中这样做:

IO.write(filepath, File.open(filepath) {|f| f.read.gsub(//<appId>\d+<\/appId>/, "<appId>42</appId>"/)})

IO.write truncates the given file by default, so if you read the text first, perform the regex String.gsub and return the resulting string using File.open in block mode, it will replace the file's content in one fell swoop. IO.write截断默认给定文件,因此,如果您先阅读文本,执行正则表达式String.gsub并返回使用生成的字符串File.open的块模式,它将取代一举文件的内容。

I like the way this reads, but it can be written in multiple lines too of course: 我喜欢它读取的方式,但它当然也可以写成多行:

IO.write(filepath, File.open(filepath) do |f|
    f.read.gsub(//<appId>\d+<\/appId>/, "<appId>42</appId>"/)
  end
)

string.gsub(/^(matchline)$/, 'X\\1X') Uses a backreference (\\1) to get the first capture group of the regex, and surround it with X string.gsub(/^(matchline)$/, 'X\\1X')使用反向引用(\\ 1)来获取正则表达式的第一个捕获组,并用X包围它

Example: 例:

string = "test\nfoo\ntest\nbar"
string.gsub!(/^test$/, 'X\&X')
p string
=> "XtestX\nfoo\nXtestX\nbar"

If your file is input.txt , I'd do as following 如果你的文件是input.txt ,我会这样做

File.open("input.txt") do |file|
  file.lines.each do |line|
    puts line.gsub(/^(.*)$/, 'X\1X')
  end
end
  • (.*) allows to capture any characters and makes it a variable Regexp (.*)允许捕获任何字符并使其成为变量Regexp
  • \\1 in the string replacement is that captured group 字符串替换中的\\1是捕获的组

If you prefer to do it in one line on the whole content, you can do it as following 如果您希望在整个内容的一行中执行此操作,则可以执行以下操作

 File.read("input.txt").gsub(/^(.*)$/, 'X\1X')

Chomp Line Endings Chomp Line Endings

Your lines probably have newline characters. 你的行可能有换行符。 You need to handle this one way or another. 你需要以这种或那种方式处理这种方式。 For example, this works fine for me: 例如,这对我来说很好:

$ ruby -ne 'puts "X#{$_.chomp}X"' /tmp/corpus
XtestX
XfooX
XtestX
XbarX

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM