我在学拉丁语,正在使用正则表达式。不确定正则表达式是否是语言不可知的,但这里是我要做的。
如果我有一个包含两个字段的表:tweet id和tweet,那么我希望遍历每条tweet并提取最多3条提到的内容。
因此,如果一条tweet出现类似“@tim bla@sam@joe something bla bla”的内容,那么该tweet的行项目将具有tweet id,tim,sam,joe。
原始数据有twitter id而不是实际的句柄,所以这个正则表达式似乎返回了一个提及 (.*)@user_(\\S{8})([:| ])(.*)
以下是我尝试过的:
a = load 'data.txt' AS (id:chararray, tweet:chararray);
b = foreach a generate id, LOWER(tweet) as tweet;
// filter data so only tweets with mentions
c = FILTER b BY tweet MATCHES '(.*)@user_(\\S{8})([:| ])(.*)';
// try to pull out the mentions.
d = foreach c generate id,
REGEX_EXTRACT(tweet, '((.*)@user_(\\S{8})([:| ])(.*)){1}',3) as mention1,
REGEX_EXTRACT(tweet, '((.*)@user_(\\S{8})([:| ])(.*)){1,2}',3) as mention2,
REGEX_EXTRACT(tweet, '((.*)@user_(\\S{8})([:| ])(.*)){2,3}',3) as mention3;
e = limit d 20;
dump e;
在那次尝试中,我使用了量词,试图返回tweet{1},{1,2},{2,3}中匹配的第一、第二和第三个示例。
那没用,提1-3都是空的。
所以我试着改变d:
d = foreach c generate id,
REGEX_EXTRACT(tweet, '(.*)@user_(\\S{8})([:| ])(.*)',2) as mention1,
REGEX_EXTRACT(tweet, '(.*)@user_(\\S{8})([:| ])(.*)@user_(\\S{8})([:| ])(.*)',5) as mention2,
REGEX_EXTRACT(tweet, '(.*)@user_(\\S{8})([:| ])(.*)@user_(\\S{8})([:| ])(.*)@user_(\\S{8})([:| ])(.*)',8) as mention3,
但是,它没有返回每个用户提到的内容,而是返回了相同的内容3次。我原以为,通过再次剪切粘贴表达式,我会得到第二个匹配项,第三次粘贴则会得到第三个匹配项。
我不确定我对这个问题的理解有多好,但换一种说法,假设函数regex\u extract()返回一个匹配项的数组。我想在一个行项目上获得提及[0]、提及[1]、提及[2]。
1条答案
按热度按时间oprakyz71#
无论何时使用pattern\u extract或pattern\u extract\u all udf,请记住它只是由java处理的纯regex。
通过本地java测试来测试regex更容易。以下是我认为可以接受的正则表达式:
对于这个正则表达式,如果至少有一个提及,它将返回三个字段,如果没有找到第二个/第三个提及,则第二个和/或第三个字段为空。
因此,您可以使用以下清管器代码:
你甚至不需要先过滤数据。