Ruby正则表达式求值只工作一次
我正在用ruby设计一个工具,根据提供的正则表达式映射解析文件中的数据。我设计了一个正则表达式,用于解析如下表声明语句:Ruby正则表达式求值只工作一次,ruby,regex,Ruby,Regex,我正在用ruby设计一个工具,根据提供的正则表达式映射解析文件中的数据。我设计了一个正则表达式,用于解析如下表声明语句: Employees(INTEGER ID UNIQUE AUTOINCREMENT, TEXT NAME, TEXT POSITION); Sales(INTEGER ID, INTEGER EMP_ID, REAL MONEY, TEXT DATE); 当我尝试使用正则表达式和下面提供的方法解析包含此数据的文件时,它似乎只解析Employees表的数据,而不是Sale
Employees(INTEGER ID UNIQUE AUTOINCREMENT, TEXT NAME, TEXT POSITION);
Sales(INTEGER ID, INTEGER EMP_ID, REAL MONEY, TEXT DATE);
当我尝试使用正则表达式和下面提供的方法解析包含此数据的文件时,它似乎只解析Employees表的数据,而不是Sales表的数据。此外,如果我像这样在员工和销售人员之间添加一行,它将卡在matchdata=regex.match行上:
Employees(INTEGER ID UNIQUE AUTOINCREMENT, TEXT NAME, TEXT POSITION);
Customers(INTEGER ID UNIQUE AUTOINCREMENT, TEXT NAME, TEXT DATA, TEXT PURCHASE_ID);
Sales(INTEGER ID, INTEGER EMP_ID, REAL MONEY, TEXT DATE);
以下是有关的正则表达式:
(?<name>[a-zA-Z0-9_]+)\((?<parameters>(?:[\s,]*[a-zA-Z]+\s*)+)(?:\);)
(?[a-zA-Z0-9\]+)\((?(?:[\s,]*[a-zA-Z]+\s*)+(?:\);)
这是我的测试程序:
require_relative '../main/regex_data_parser.rb'
parser = RegexParser.new
parser.add_regex('Sqlite_Table', /(?<name>[a-zA-Z0-9_]+)\((?<parameters>(?:[\s,]*[a-zA-Z]+\s*)+)(?:\);)/)
ddl_file = ARGV[0]
if ddl_file.length < 1 then
puts 'No Input File provided.'
else
parser.parse_file ddl_file
parser.print_debug
end
require_relative'../main/regex_data_parser.rb'
parser=RegexParser.new
parser.add_regex('Sqlite_Table',/(?[a-zA-Z0-9\]+)\((?(?:[\s,]*[a-zA-Z]+\s*)+)(?:\)/)
ddl_文件=ARGV[0]
如果ddl_file.length<1,则
放入“未提供输入文件”
其他的
parser.parse_文件ddl_文件
parser.print\u调试
结束
下面是我用来解析数据的方法(从RegexParser调用):
#根据提供的正则表达式解析文件中的数据。
def解析_文件(文件)
#如果正则表达式为null,则退出该方法,错误代码为-1
if@regex|u mappings.nil?|@regex_.empty?然后
返回-1
结束
#遍历文件,扫描数据
@数据_映射={}
File.foreach(File)do |行|
将“扫描:”+行放入
#汇编匹配数据
@regex|u映射。每个do|obj|u名称,regex|
为“+obj_名称”放置“装配匹配数据”
matchdata=regex.match行
将“匹配数据集合”
如果!matchdata.nil?然后
puts'找到匹配数据。正在查找捕获组的名称。”
#检索匹配的捕获组的名称
keys=matchdata.names
如果!零?然后
找到匹配的组。查找属性'
#初始化此键的映射
如果@数据映射.key?那么你的名字呢
将“初始化对象数组:”+对象名称
@数据映射[obj_名称]=[]
结束
#初始化行数据数组
行_数据=[]
钥匙。每个do |钥匙|
#查找此行上每个匹配捕获组的值。
值=匹配数据[键]
#将映射添加到线数据数组
line_data这个问题源于这样一个事实:这个表达式(?:[\s,]*[a-zA-Z]+\s*)+
这对发动机来说太复杂了。回溯路径太多
如果您将其更改为(?:[\s,]*[a-zA-Z]\s*)+
,它将工作
但是,唯一要做的就是确保至少有一个
alpha字符,它不强制任何带有逗号的形式
如果你不在乎字母或逗号,你可以用这个
# (?<name>[a-zA-Z0-9_]+)\((?<parameters>[a-zA-Z\s,]+)\)\;
(?<name> [a-zA-Z0-9_]+ ) # (1)
\(
(?<parameters> # (2 start)
[a-zA-Z\s,]+
) # (2 end)
\)\;
(?[a-zA-Z0-9\]+)\((?[a-zA-Z\s,]+)\);
(?[a-zA-Z0-9+)(1)
\(
(?#(2开始)
[a-zA-Z\s,]+
)#(二完)
\)\;
但是,如果您确实关心表单,那么您至少需要一个alpha
在逗号之间,可以使用如下修改的展开循环方法
# (?<name>[a-zA-Z0-9_]+)\((?<parameters>(?:\s*[a-zA-Z])+(?:,(?:\s*[a-zA-Z])+)*\s*)\)\;
(?<name> [a-zA-Z0-9_]+ ) # (1)
\(
(?<parameters> # (2 start)
(?:
\s*
[a-zA-Z]
)+
(?:
,
(?:
\s*
[a-zA-Z]
)+
)*
\s*
) # (2 end)
\)\;
(?[a-zA-Z0-9.]+)\((?(?:\s*[a-zA-Z])+(?:,(?:\s*[a-zA-Z])+)*\s*)\;
(?[a-zA-Z0-9+)(1)
\(
(?#(2开始)
(?:
\s*
[a-zA-Z]
)+
(?:
,
(?:
\s*
[a-zA-Z]
)+
)*
\s*
)#(二完)
\)\;
使用两个空格缩进Ruby代码,而不是多/少/制表符等字符类中缺少下划线。作为一种旁白,使用量词{1}
是无用的,请删除它们<代码>、
和代码>不是特殊字符,您不需要转义它们。我已经删除了额外的量词/转义斜杠。我还要记住两个空格的缩进规则。Casimir,下划线正是缺少的。真不敢相信我没看到。多谢各位@JohnRiley-即使添加下划线,当遇到部分形式时,仍然会遇到相同的问题。它要么挂起来,要么在很长一段时间后回来。
# (?<name>[a-zA-Z0-9_]+)\((?<parameters>(?:\s*[a-zA-Z])+(?:,(?:\s*[a-zA-Z])+)*\s*)\)\;
(?<name> [a-zA-Z0-9_]+ ) # (1)
\(
(?<parameters> # (2 start)
(?:
\s*
[a-zA-Z]
)+
(?:
,
(?:
\s*
[a-zA-Z]
)+
)*
\s*
) # (2 end)
\)\;