3

Pig での文字列解析に行き詰まっています。

私は周りのドキュメントを見て、それらの関数のいずれかを使用したいと考えていましたregex_extractregex_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)。また、1 ユーザーあたりのフレンド数が 3 人を超えたり、少なかったりする場合もあります。

何か案は?

また、次のようなものを使用してFLATTEN(TOKENIZE($0,'&'))から、どういうわけかそのようなものだけをフィルタリングすることも検討してSUBSTRING($0,0,INDEXOF($0,'=')) == 'friend'いますが、誰かが適切な正規表現のアプローチを知っているかどうかを確認したかったのです。

4

2 に答える 2

2

これは、単純な文字列操作で実現できます。

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)
于 2013-11-28T00:36:49.383 に答える