有没有办法匹配RE2中指定字符的前后?

时间:2018-08-03 14:45:07

标签: regex google-bigquery re2

我需要在较大的文档中找到可能是信用卡详细信息的数字,例如346490606109917。我想忽略其中包含信用卡样式详细信息的较大数字,例如96213464906061099171

在常规的RegEx中(如果您会喜欢双关语,请在模式的开头使用(?<![0-9]),在结尾使用(?![0-9]),以便仅使用与信用卡完全匹配的数字格式将被匹配,并且其中可能包含信用卡样式编号的较大数字将被忽略。数字两侧的非数字字符都可以。

我的模式是

(?<![0-9])(4[0-9]{12}(?:[0-9]{3})?|(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})(?![0-9])

例如,在正常的RegEx中,它会在abc346490606109917zyz上产生匹配项,而不会在abc96213464906061099171xyz上产生匹配项。

但是this isn't supported in Regex2是BigQuery所使用的-在文档中列为“不支持”。

RE2中是否存在等效项?或者不可能吗?

1 个答案:

答案 0 :(得分:1)

以下是用于BigQuery标准SQL

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 'abc346490606109917zyz' str UNION ALL
  SELECT 'abc96213464906061099171xyz'
)
SELECT *, REGEXP_CONTAINS(str, r'(^|[^0-9])(4[0-9]{12}(?:[0-9]{3})?|(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})($|[^0-9])') check
FROM `project.dataset.table`   

结果低于

Row str                         check    
1   abc346490606109917zyz       true     
2   abc96213464906061099171xyz  false      

(^|[^0-9])部分标识字符串的开头或非数字序列。与($|[^0-9])相同,但不是开始,而是指示字符串或非数字序列的结尾

如果您还需要提取卡号-请使用以下示例

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 'abc346490606109917zyz' str UNION ALL
  SELECT 'abc96213464906061099171xyz'
)
SELECT *, 
  REGEXP_CONTAINS(str, r'(^|[^0-9])(4[0-9]{12}(?:[0-9]{3})?|(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})($|[^0-9])') check,
  REGEXP_EXTRACT(str, r'(?:^|[^0-9])(4[0-9]{12}(?:[0-9]{3})?|(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})(?:$|[^0-9])') number
FROM `project.dataset.table`   

结果将是

Row str                         check   number   
1   abc346490606109917zyz       true    346490606109917  
2   abc96213464906061099171xyz  false   null        

在这里,您需要在REGEXP_EXTRACT中使用(?:regular_expression)来表示非捕获组