pig - 用正则表达式解析字符串
Posted
技术标签:
【中文标题】pig - 用正则表达式解析字符串【英文标题】:pig - parsing string with regex 【发布时间】:2013-01-03 02:12:36 【问题描述】:我被 Pig 中的字符串解析困住了。
我查看了有关regex_extract
和regex_extract_all
的文档,并希望使用其中一个功能。
我有文件'/logs/test.log'
:
cat '/logs/test.log'
user=242562&friend=6226&friend=93856&age=35&friend=35900
我想从 url 中提取 friend
标签,在这种情况下,我有 3 个相同的标签。 regex_extract
似乎只适用于第一个实例,这是我所期望的,而对于 regex_extract_all
,我似乎知道整个字符串模式,它在源文件的每一行都会发生变化。
regex_extract
看起来不错,但这个选项只给了我第一个。
[root@test]# pig -x local
A = LOAD './test.log';
B = FOREACH A GENERATE REGEX_EXTRACT($0, 'friend=([0-9]*)',1);
dump B;
(6226)
我看到的regex_extract_all
的例子显示了你寻找所有标签的正则表达式:
B = FOREACH A GENERATE FLATTEN(REGEX_EXTRACT_ALL($0, 'user=([0-9]+?)&friend=([0-9]+?)&friend=([0-9]+?)&.+?'));
dump B;
(242562,6226,93856)
这似乎可行,但我真的只想提取朋友 - (6226,93856,35900)。我也有一些情况,每个用户的朋友可能多于或少于 3 个。
有什么想法吗?
还考虑使用FLATTEN(TOKENIZE($0,'&'))
之类的东西,然后以某种方式只过滤SUBSTRING($0,0,INDEXOF($0,'=')) == 'friend'
或类似的东西,但想看看是否有人知道一个好的正则表达式方法。
【问题讨论】:
Kinda 放弃了这一点,只是将 STREAM 用于我编写的快速脚本。不想再维护另一个脚本,但解决方案要快得多。后悔花了这么多时间试图让它在本地工作 【参考方案1】:这可以通过简单的字符串操作来实现:
inputs = LOAD 'input' AS (line: chararray);
tokenized = FOREACH inputs GENERATE FLATTEN(TOKENIZE(line, '&')) AS parameter;
filtered = FILTER tokenized BY INDEXOF(parameter, 'friend=') != -1;
result = FOREACH filtered GENERATE SUBSTRING(parameter, 7, (int)SIZE(parameter)) AS friend_number;
DESCRIBE tokenized;
DUMP tokenized;
DESCRIBE filtered;
DUMP filtered;
DESCRIBE result;
DUMP result;
结果:
tokenized: parameter: chararray
(user=242562)
(friend=6226)
(friend=93856)
(age=35)
(friend=35900)
filtered: parameter: chararray
(friend=6226)
(friend=93856)
(friend=35900)
result: friend_number: chararray
(6226)
(93856)
(35900)
【讨论】:
【参考方案2】:试试这个:
a = LOAD '/logs/test.log' USING PigStorage('&') as (f1, f2, f3, f4, f5);
b = FOREACH a GENERATE REGEX_EXTRACT(f2,'friend=([0-9]*)', 1),
REGEX_EXTRACT(f3,'friend=([0-9]*)', 1),
REGEX_EXTRACT(f5,'friend=([0-9]*)', 1);
DUMP b;
【讨论】:
以上是关于pig - 用正则表达式解析字符串的主要内容,如果未能解决你的问题,请参考以下文章