Ruby:如何在包含特定字母序列的字符串中复制单词?

时间:2015-06-17 17:54:08

标签: ruby regex

我正在尝试阅读文本文件并遍历每一行。如果该行包含" _u"然后我想在那一行复制那个词。

例如:

typedef struct {
    reg 1;
    reg 2;
} buffer_u;

我想复制一下buffer_u。

这是我到目前为止所做的一切(如何复制字符串中的单词):

f_in = File.open( h_file )
test = h_file.read  
text.each_line do |line|
    if line.include? "_u"
        # copy word
        # add to output file
    end
end

提前感谢您的帮助!

4 个答案:

答案 0 :(得分:3)

不要让它变得更难。如果要扫描文本正文以查找符合条件的单词,请执行以下操作:

text = "
word_u1
something
_u1 foo
bar _u2
another word_u2
typedef struct {
    reg 1;
    reg 2;
} buffer_u;
"

text.scan(/\w+/).select{ |w| w['_u'] }
# => ["word_u1", "_u1", "_u2", "word_u2", "buffer_u"]

正则表达式很有用,但它们越复杂(#34;更聪明"),它们运行速度越慢,除非你非常小心地锚定它们,因为锚点会给出它们在哪里看的提示。如果没有这些,引擎会尝试很多东西来确定你想要的东西,这可能会使处理陷入困境。

我建议只需抓住文字中的字词:

scan(/\w+/)

然后过滤掉匹配的那些:

select{ |w| w['_u'] }

使用带有简单子字符串搜索w['_u']的select非常快。

使用split()代替scan(/\w+/)可能会更快地运行,但您必须处理清理非字字符。

注意:\w表示[a-zA-Z0-9_]所以我们通常称之为" word"字符实际上是一个"变量"大多数语言的定义,因为单词通常不包含数字或_

您可以将代码缩减为:

File.read( h_file ).scan(/\w+/).select{ |w| w['_u'] }

这将返回一组匹配的单词。

警告:使用read存在可伸缩性问题。如果您关注正在读取的文件的大小(您应该总是这样),那么请使用foreach并逐行遍历文件。您可能会看到处理速度没有变化。

答案 1 :(得分:0)

您可以尝试这样的事情:

words = []
File.open( h_file ) { |file| file.each_line { |line|
  words << line.split.find { |a| a =~ /_u/ }
}}

words.compact!
# => [["buffer_u"]]

puts words
# buffer_u

答案 2 :(得分:0)

此正则表达式应该以{{1​​}}

结尾
_u

匹配组将匹配以_u结尾的单词后跟字母数字或下划线。

如果您希望_u出现在单词的任何位置,请使用

(\w*_u)(?!\w)

请参阅DEMO here

答案 3 :(得分:-1)

这将返回文件中的所有这些单词,即使一行中有两个或更多单词:

r = /
    \w*           # match >= 0 word characters
    _u            # match string
    \w*           # match >= 0 word characters 
    /x            # extended mode

File.read(fname).scan r

例如:

str = "Cat_u has 9 lives, \n!dog_u has none and \n pig_u_o and cow_u, 3."

fname = 'temp'
File.write(fname, str)
  #=> 63

确认文件内容:

File.read(fname)
  #=> "Cat_u has 9 lives, \n!dog_u has none and \n pig_u_o and cow_u, 3."

提取字符串:

File.read(fname).scan r
  #=> ["Cat_u", "dog_u", "pig_u_o", "cow_u"] 

修改此代码以使每行最多返回一个字符串并不困难。只需将文件读入一行数组(或一次读一行),然后为每一行执行s = line[r]; arr << s if s,其中r是上述正则表达式。