regex返回所有值,而不仅仅是第一次找到的值

regex返回所有值,而不仅仅是第一次找到的值,regex,apache-pig,Regex,Apache Pig,我正在学习拉丁语,正在使用正则表达式。不确定正则表达式是否是语言不可知的,但下面是我要做的 如果我有一个包含两个字段的表:tweet id和tweet,我希望浏览每个tweet,并将所有提到的内容提取到3个 因此,如果一条tweet类似于“@tim bla@sam@joe something bla bla”,那么该tweet的行项目将具有tweet id,tim,sam,joe 原始数据的twitter ID不是实际的句柄,因此此正则表达式似乎返回一个提词(.*)@user\uz(\\S{8}

我正在学习拉丁语,正在使用正则表达式。不确定正则表达式是否是语言不可知的,但下面是我要做的

如果我有一个包含两个字段的表:tweet id和tweet,我希望浏览每个tweet,并将所有提到的内容提取到3个

因此,如果一条tweet类似于“@tim bla@sam@joe something bla bla”,那么该tweet的行项目将具有tweet id,tim,sam,joe

原始数据的twitter ID不是实际的句柄,因此此正则表达式似乎返回一个提词
(.*)@user\uz(\\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次相同的提及。我原以为,通过剪切n再次粘贴表达式,我将获得第二个匹配,而第三次粘贴将获得第三个匹配


我不确定我对这个问题的理解有多好,但换一种说法,假设函数regex_extract()返回一个匹配项数组。我希望在一行项目上提到[0]、提到[1]、提到[2]。

无论何时使用PATTERN\u EXTRACT或PATTERN\u EXTRACT\u ALL udf,请记住它只是由Java处理的纯正则表达式

通过本地Java测试更容易测试正则表达式。以下是我认为可以接受的正则表达式:

Pattern p = Pattern.compile("@(\\S+).*?(?:@(\\S+)(?:.*?@(\\S+))?)?");

String input = "So if a tweet goes something like @tim bla @sam @joe @bill something bla bla";
Matcher m = p.matcher(input);
if(m.find()){
    for(int i=0; i<=m.groupCount(); i++){
        System.out.println(i + " -> " + m.group(i));
    }
}

您甚至不需要先过滤数据。

请发布一些示例输入。如果您的正则表达式包含@user\u,它将查找包含单词“user\u”的用户名。\S+将匹配任何非空白字符,匹配用户,如
@sam、
@bob。
是。但在介绍中,Doug说“如果一条tweet类似“@tim bla@sam@joe something bla bla bla”,那么该tweet的行项目将有tweet id,tim,sam,joe.”,这与Regex冲突,Regex只保留以user_u开头的用户名。因此,我没有假设任何关于用户名的具体规则。谢谢。当我回到我的hadoop界面时,我现在实际上无法测试这个,我将尝试一下。
d = foreach c generate id, REGEX_EXTRACT_ALL(
         tweet, '@(\\S+).*?(?:@(\\S+)(?:.*?@(\\S+))?)?');