我正在尝试读取一个.txt文件,在每行中搜索两个或多个空白,并使用stringScanner gem 将指针保存在匹配的位置
到目前为止,我已经设法找到了匹配,但我不知道如何保存指针
require 'strscan'
class LintFile
attr_reader :file, :lines
def initialize(filepath)
@file = File.open(filepath)
@lines = []
end
def read
# Here I get each line into an array
@file.each_with_index do |line, ind|
@lines[ind] = StringScanner.new(line)
end
end
end
def check_error(filepath)
@file_to_check = LintFile.new(filepath)
@file_to_check.read
#file_to_check.lines
#Scan each line
@file_to_check.lines.length.times do |line|
whitespace(line)
end
end
def whitespace(line)
if @file_to_check.lines[line].string.match?(" ")
#pos is not giving the pointer where the match occurred
pointer = @file_to_check.lines[line].pos
puts "Estoy dentro del unless #{pointer}"
end
end
请帮帮我!
提前感谢
假设文件包含一个字符串,该字符串被读入变量str
。例如:
str =<<~_
Now is the time for
all good Rubyists to
come to the aid
of their fellow coders.
_
使用StringScanner方法
我们可以如下获得由两个或多个空间组成的每个子串的开头到串str
的偏移。如图所示,获得每行的偏移量(而不是str
(是对我将描述的计算的直接修改。
require 'strscan'
def scan_it(str)
s = StringScanner.new(str)
arr = []
until s.eos?
ss = s.scan(/ {2,}/)
if ss
arr << s.pos - ss.size
else
s.scan(/ ?[^ ]+/)
end
end
arr
end
我们获得:
arr = scan_it(str)
#=> [6, 46, 56, 79]
让我们检查str
中那些偏移量周围的子字符串。
arr.map { |n| puts str[n-3,10] }
is the t
ome to
the aid
low cod
正则表达式/ {2,}/
匹配两个或多个空格。正则表达式/ ?[^ ]+/
匹配除空格([^ ]
(之外的一个或多个(+
(字符,可选地在其前面加一个空格(?
(。
s.scan
的匹配项如下表所示。(第一列中的下划线表示空格。(
ss regex matched s.pos s.pos-ss.size
-----------------------------------------------
Now / ?[^ ]+/ 3
_is / ?[^ ]+/ 6
__ / {2,}/ 8 6
the / ?[^ ]+/ 11
_time / ?[^ ]+/ 16
_fornall / ?[^ ]+/ 24
_good / ?[^ ]+/ 29
_Rubyists / ?[^ ]+/ 38
_toncome / ?[^ ]+/ 46
____ / {2,}/ 50 46
to / ?[^ ]+/ 52
_the / ?[^ ]+/ 56
____ / {2,}/ 60 56
aidnof / ?[^ ]+/ 66
_their / ?[^ ]+/ 72
_fellow / ?[^ ]+/ 79
____ / {2,}/ 83 79
coders. / ?[^ ]+/ 90
获取每条线的偏移
str.each_line.with_index.with_object({}) do |(line,i),h|
h[i] = scan_it(line)
end
#=> {0=>[6], 1=>[], 2=>[4, 14], 3=>[15]}
这表明在第一行(行偏移0
(中有两个或多个空格的一个子串,从偏移6
开始,在第二行中没有子串,在第三行中有两个子串,在偏移4
和14
开始,在最后一行中有一子串,从偏置15
开始。
请参阅字符串#each_line、枚举器#with_index和枚举器#with_object。
使用字符串#gsub
这里有一种不使用StringScanner
的计算所需偏移的更简单方法。
str.gsub(/ {2,}/).map { |_,arr| Regexp.last_match.begin(0) }
#=> [6, 46, 56, 79]
这使用了String#gsub
的形式,它只接受一个参数(模式(而不接受块。这返回一个枚举器,该枚举器仅生成匹配项(每个匹配项由两个或多个空格组成的字符串(,并且不执行替换(使名称gsub
有些混乱(。我已将枚举器链接到Enumerable#映射。
每个匹配都由第一个块变量保持。我为该变量使用了下划线,以向读者表明它没有用于块计算(这是一种常见的做法(。
另请参阅Regexp::last_match,它返回一个MatchData
对象,以及MatchData#begin,它为我们提供了当前匹配开始的偏移量。
获取两个或多个空间的子字符串的行内的行和位置开始
str.each_line.with_index.with_object({}) do |(line,i),h|
h[i] = line.gsub(/ {2,}/).map { |_,arr| Regexp.last_match.begin(0) }
end
#=> {0=>[6], 1=>[], 2=>[4, 14], 3=>[15]}