BigQuery REGEXP_MATCH和重音:边界通配符失败?

时间:2014-03-04 00:23:13

标签: regex google-apps-script google-bigquery

在GAS中,我可以正确地将重音符号与具有边界字符的正则表达式匹配,例如\bà\ b。字符à仅在它是单独的单词时才匹配。这适用于GAS:

function test_regExp() {
  var str = "la séance est à Paris";
  var RegExp = "\\bà\\b";
  var PatReg= new RegExp( RegExp);
  var found=PatReg.exec(str);
  if (found) {
    Logger.log( [str.substring(0,found.index),found[0],str.substring(found[0].length+found.index)] );
  } else Logger.log("oops! Did not match");

在BigQuery中,如果边界字符位于重音符号旁边,则模式不匹配。 \bséance\ b匹配séance:

SELECT [row],etext,ftext FROM [hcd.hdctextx] WHERE (REGEXP_MATCH(ftext,"\\bséance\\b") ) LIMIT 100;

\bà\ b与à不匹配:

SELECT [row],etext,ftext FROM [hcd.hdctextx] WHERE (REGEXP_MATCH(ftext,"\\bà\\b") ) LIMIT 100;

我假设BigQuery与GAS不同,它在边界字符集中包含重音符号。所以\bséance\ b有效,因为é可以在该配置中作为边界正常运行。 \bà\ b或\bétranger\ b或\bmarché\ b不起作用,因为重音+ \ b被解释为\ b \ b,它永远不会匹配任何东西。 (好吧,我在这里抓住稻草,因为我找不到更好的解释......除了一个错误。)

我不认为这是一个unicode问题,因为它只会出现在边界位置。

因此,目前无法在这些特定的重音配置中使用边界。

有没有办法在BigQuery或其他修复程序中设置Locale?

解决方法:替换(?:[^ a-zA-Zéàïëâê])等等\ b。

谢谢!

3 个答案:

答案 0 :(得分:5)

检查出来:

SElect Regexp_extract(StringToParse,r'\b?(à)\b?') as Extract,
 Regexp_match(StringToParse,r'\b?(à)\b?') as match,
FROM
(SELECT 'la séance est à Paris' as StringToParse)

希望这有帮助

答案 1 :(得分:4)

关于RE2 syntax documentation,BigQuery的行为是正确的。 (毫不奇怪,因为BigQuery使用RE2来实现regexp。)

RE2的角色类是:

\b = at word boundary (\w on one side and \W, \A, or \z on the other)
\w = word characters (≡ [0-9A-Za-z_])
\W = not word characters (≡ [^0-9A-Za-z_])
\A = beginning of text
\z = end of text

换句话说,您只能使用\ b来匹配非重音字符的边界。 RE2对Unicode字符有很多支持,所以你最有可能使用像\ pL这样的东西来制作一个替代的正则表达式。

我不确定为什么Google Apps脚本不会遵循此处的RE2规范,但我会跟进该团队以了解正在发生的事情。

答案 2 :(得分:2)

答案是:在BQ中不要使用带有重音符的 \ b ;重写常规表达:

frenRegExp = frenRegExp.replace(/\\b/g, "(?:[- .,;!?()]|$|^)");      
frenRegExp = frenRegExp.replace(/\\w/g, "(?:[A-Za-zÀàÂâÄäÆæÇçÈèÉéÊêËëÎîÏïÔôÙùÛûÜüñ])"); 
frenRegExp = frenRegExp.replace(/\\W/g, "(?:[^A-Za-zÀàÂâÄäÆæÇçÈèÉéÊêËëÎîÏïÔôÙùÛûÜüñ])");  

此外,虽然GAS规范有RE2作为其引擎(哎呀!我真的不知道它的用途,因为它不排除来自\ w的重音字符,如BQ),它只是部分实现。例如, \ pL 与字母不匹配。

以下是一些适用于应用脚本的测试代码,但在没有替换的情况下不在BQ中。

////////////////////// TEST ///////////////////

function test_regExp() {
  var str = " Voilà la séance générale qui est à Paris";
  var RegExpString ="\\bs\\w+an\\w*"
  Logger.log(RegExpString);
  var RegExpCompiled= new RegExp( RegExpString,"i");
  Logger.log(RegExpCompiled.source); 
  var found=RegExpCompiled.exec(str);
  if (found) {
    Logger.log("|"+found[0]+"|")
    Logger.log( [str.substring(0,found.index),found[0],str.substring(found[0].length+found.index)] );
  } else Logger.log("Oops: not found");

}

输出:

[16-02-09 22:15:59:659 PST] \bs\w+anc\w*
[16-02-09 22:15:59:660 PST] \bs\w+an\w*
[16-02-09 22:15:59:660 PST] |séance|
[16-02-09 22:15:59:661 PST] [ Voilà la , séance,  générale qui est à Paris]
相关问题