5

我正在尝试采用逻辑匹配标准,例如:

(("Foo" OR "Foo Bar" OR FooBar) AND ("test" OR "testA" OR "TestB")) OR TestZ

并将其应用为与 pig 中的文件的匹配项

result = filter inputfields by text matches (some regex expression here));

问题是我不知道如何将上面的逻辑表达式转换为匹配方法的正则表达式。

我摆弄了各种各样的东西,我最接近的是这样的:

((?=.*?\bFoo\b | \bFoo Bar\b))(?=.*?\bTestZ\b)

有任何想法吗?如果可能,我还需要尝试以编程方式进行此转换。

一些例子:

a - 快速的棕色 Foo 跳过了惰性测试(这应该通过,因为它包含 foo 和测试)

b - TestZ 中发生的事情(这也通过了,因为它包含 testZ)

c - 快速的棕色 Foo 跳过了懒狗(这应该会失败,因为它包含 Foo 但不包含 test、testA 或 TestB)

谢谢

4

2 回答 2

13

由于您使用的是 Pig,您实际上并不需要涉及的正则表达式,您可以使用 pig 提供的布尔运算符和几个简单的正则表达式,例如:

T = load 'matches.txt' as (str:chararray);
F = filter T by ((str matches '.*(Foo|Foo Bar|FooBar).*' and str matches '.*(test|testA|TestB).*') or str matches '.*TestZ.*');
dump F;
于 2013-09-01T11:56:35.103 回答
1

您可以将此正则表达式用于matches方法

^((?=.*\\bTestZ\\b)|(?=.*\\b(FooBar|Foo Bar|Foo)\\b)(?=.*\\b(testA|testB|test)\\b)).*
  • 请注意,"Foo" OR "Foo Bar" OR "FooBar"应该写成FooBar|Foo Bar|FooFoo|Foo Bar|FooBar阻止仅在包含或Foo的字符串中匹配FooBarFoo Bar
  • 此外,由于前瞻是零宽度,您需要.*在正则表达式的末尾传递以让匹配匹配整个字符串。

演示

String[] data = { "The quick brown Foo jumped over the lazy test",
        "the was something going on in TestZ",
        "the quick brown Foo jumped over the lazy dog" };
String regex = "^((?=.*\\bTestZ\\b)|(?=.*\\b(FooBar|Foo Bar|Foo)\\b)(?=.*\\b(testA|testB|test)\\b)).*";
for (String s : data) {
    System.out.println(s.matches(regex) + " : " + s);
}

输出:

true : The quick brown Foo jumped over the lazy test
true : the was something going on in TestZ
false : the quick brown Foo jumped over the lazy dog
于 2013-09-01T11:53:39.677 回答