在字符串中查找点分隔的单词
Find Dot Separated Words in a String
我需要解析日志文件以找出与以下不区分大小写的模式匹配的字符串:
libname.data <--- Okay
libname.* <--- Not okay
对于那些有 SAS 经验的人,我正在尝试从大型日志中获取 SAS 数据集名称。
所有字符串都是 space 分隔的。一些行的例子:
NOTE: The data set LIBNAME.DATA has 428 observations and 15 variables.
MPRINT(MYMACRO): data libname.data;
MPRINT(MYMACRO): create table libname.data(rename=(var1 = var2)) as select distinct var1, var2 as
MPRINT(MYMACRO): format=date. from libname.data where ^missing(var1) and ^missing(var2) and
我试过的
这个 PERL 正则表达式:
/^(?!.*[.*]{2})[a-z0-9*_:-]+(?:\.[a-z0-9;_:-]+)+$/mi
https://regex101.com/r/jYkXn5/1
在 SAS 代码中:
data test;
line = 'words and stuff libname.data';
test = prxmatch('/^(?!.*[.*]{2})[a-z0-9*_:-]+(?:\.[a-z0-9;_:-]+)+$/mi', line);
run;
问题
当该行只包含这个确切的字符串时,这将起作用,但如果该行包含其他字符串,它将不起作用。
解决方案
谢谢,瞎子!
我从日志中解析 SAS 数据集的正则表达式是:
/(?!.*[.*]{3})[a-z_]+[a-z0-9_]+(?:\.[a-z0-9_]+)/mi
data test;
line = 'NOTE: COMPRESSING DATA SET LIBNAME.DATA DECREASED SIZE BY 46.44 PERCENT';
prxID = prxparse('/(?!.*[.*]{3})[a-z]+[a-z0-9_]+(?:\.[a-z0-9_]+)/mi');
call prxsubstr(prxID, line, position, length);
dataset = substr(line, position, length);
run;
这仍然会提取一些 SQL select 语句,但这很容易通过 post-processing 解决。
您在开头锚定了表达式,只需删除第一个 ^
即可。
/(?!.*[.*]{2})[a-z0-9*_:-]+(?:\.[a-z0-9;_:-]+)+$/mi
开头的前瞻防止匹配 ..
但模式本身不会匹配,因为字符 classes 重复 1 次或多次并且不包含点。
如果你不想同时匹配**
,并且字符串不应以*
开头,你可以将其添加到字符class [*.]
连同点,从第一个字符class.
中取出
在那种情况下,您可以省略正面前瞻和锚点:
/[a-z0-9_:-]+(?:[.*][a-z0-9_:-]+)+/i
由于模式不包含任何锚点,您可以省略 m
标志。
您只需在日志文件行中找到以下标志性文本即可。
... data set <LIBNAME>.<MEMNAME> ...
如果数据集名称在日志中,您可以假定它的格式正确。
data want;
length line 00;
infile LOG_FILE lrecl=1000 length=L;
input line $VARYING. L;
* literally "data set <name>" followed by space or period;
rx = prxparse('/data set (.*?)\.(.*?)[. ]/');
if prxmatch(rx,line) then do;
length libname memname ;
libname = prxposn(rx,1,line);
memname = prxposn(rx,2,line);
line_number = _n_;
output;
end;
keep libname memname line_number;
run;
如果数据集名称是 '<anything>'N
形式的名称文字,则需要进行一些调整
Web 上还有大量现有的 SAS 日志文件解析器和分析器可供您使用。
我需要解析日志文件以找出与以下不区分大小写的模式匹配的字符串:
libname.data <--- Okay
libname.* <--- Not okay
对于那些有 SAS 经验的人,我正在尝试从大型日志中获取 SAS 数据集名称。
所有字符串都是 space 分隔的。一些行的例子:
NOTE: The data set LIBNAME.DATA has 428 observations and 15 variables.
MPRINT(MYMACRO): data libname.data;
MPRINT(MYMACRO): create table libname.data(rename=(var1 = var2)) as select distinct var1, var2 as
MPRINT(MYMACRO): format=date. from libname.data where ^missing(var1) and ^missing(var2) and
我试过的
这个 PERL 正则表达式:
/^(?!.*[.*]{2})[a-z0-9*_:-]+(?:\.[a-z0-9;_:-]+)+$/mi
https://regex101.com/r/jYkXn5/1
在 SAS 代码中:
data test;
line = 'words and stuff libname.data';
test = prxmatch('/^(?!.*[.*]{2})[a-z0-9*_:-]+(?:\.[a-z0-9;_:-]+)+$/mi', line);
run;
问题
当该行只包含这个确切的字符串时,这将起作用,但如果该行包含其他字符串,它将不起作用。
解决方案
谢谢,瞎子!
我从日志中解析 SAS 数据集的正则表达式是:
/(?!.*[.*]{3})[a-z_]+[a-z0-9_]+(?:\.[a-z0-9_]+)/mi
data test;
line = 'NOTE: COMPRESSING DATA SET LIBNAME.DATA DECREASED SIZE BY 46.44 PERCENT';
prxID = prxparse('/(?!.*[.*]{3})[a-z]+[a-z0-9_]+(?:\.[a-z0-9_]+)/mi');
call prxsubstr(prxID, line, position, length);
dataset = substr(line, position, length);
run;
这仍然会提取一些 SQL select 语句,但这很容易通过 post-processing 解决。
您在开头锚定了表达式,只需删除第一个 ^
即可。
/(?!.*[.*]{2})[a-z0-9*_:-]+(?:\.[a-z0-9;_:-]+)+$/mi
开头的前瞻防止匹配 ..
但模式本身不会匹配,因为字符 classes 重复 1 次或多次并且不包含点。
如果你不想同时匹配**
,并且字符串不应以*
开头,你可以将其添加到字符class [*.]
连同点,从第一个字符class.
在那种情况下,您可以省略正面前瞻和锚点:
/[a-z0-9_:-]+(?:[.*][a-z0-9_:-]+)+/i
由于模式不包含任何锚点,您可以省略 m
标志。
您只需在日志文件行中找到以下标志性文本即可。
... data set <LIBNAME>.<MEMNAME> ...
如果数据集名称在日志中,您可以假定它的格式正确。
data want;
length line 00;
infile LOG_FILE lrecl=1000 length=L;
input line $VARYING. L;
* literally "data set <name>" followed by space or period;
rx = prxparse('/data set (.*?)\.(.*?)[. ]/');
if prxmatch(rx,line) then do;
length libname memname ;
libname = prxposn(rx,1,line);
memname = prxposn(rx,2,line);
line_number = _n_;
output;
end;
keep libname memname line_number;
run;
如果数据集名称是 '<anything>'N
Web 上还有大量现有的 SAS 日志文件解析器和分析器可供您使用。