# Pattern Capture Token Filter(模式匹配词元过滤器)

原文链接 :[https://www.elastic.co/guide/en/elasticsearch/reference/5.4/analysis-pattern-capture-tokenfilter.html](https://www.elastic.co/guide/en/elasticsearch/reference/5.4/analysis-pattern-capture-tokenfilter.html)

译文链接 : [http://www.apache.wiki/pages/viewpage.action?pageId=10028023](http://www.apache.wiki/pages/viewpage.action?pageId=10028023)

贡献者 : [李亚运](/display/~liyayun)，[ApacheCN](/display/~apachecn)，[Apache中文网](/display/~apachechina)

## 简述

`pattern_capture词元`过滤器与`pattern 分词器`不同，为正则表达式中的每个捕获组发出一个token。 

 模式不会锚定到字符串的开始和结尾，每个模式可以匹配多次，并且允许重复匹配。

小心病态正则表达式 模式捕获令牌过滤器使用[Java正则表达式](http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html) 。 一个严重的正则表达式可能会运行得非常慢，甚至会抛出一个StackOverflowError，并导致其运行的节点突然退出。 阅读更多[关于病态正则表达式和如何避免它们](http://www.regular-expressions.info/catastrophic.html) 。  

## 示例-1

举例如下：

正则：

```
"(([a-z]+)(\d*))"
```

待匹配文字：

```
"abc123def456"
```

匹配结果：

```
[ abc123, abc, 123, def456, def, 456 ]
```

如果`preserve_original`设置为`true` （默认值），那么它也会发出原始令牌： `abc123def456` 。

这对于索引文本（如驼峰式代码）特别有用，例如`stripHTML` ，用户可以在其中搜索`"strip html"`或`"striphtml"` ：

```
PUT test
{
   "settings" : {
      "analysis" : {
         "filter" : {
            "code" : {
               "type" : "pattern_capture",
               "preserve_original" : true,
               "patterns" : [
                  "(\\p{Ll}+|\\p{Lu}\\p{Ll}+|\\p{Lu}+)",
                  "(\\d+)"
               ]
            }
         },
         "analyzer" : {
            "code" : {
               "tokenizer" : "pattern",
               "filter" : [ "code", "lowercase" ]
            }
         }
      }
   }
}

```

当处理如下文本内容时：

```
import static org.apache.commons.lang.StringEscapeUtils.escapeHtml
```

结果如下：

```
[ import, static, org, apache, commons, lang, stringescapeutils, string, escape, utils, escapehtml, escape, html ]
```

## 示例-2

别一个例子就是分析邮箱时，如下所示：

```
PUT test
{
   "settings" : {
      "analysis" : {
         "filter" : {
            "email" : {
               "type" : "pattern_capture",
               "preserve_original" : true,
               "patterns" : [
                  "([^@]+)",
                  "(\\p{L}+)",
                  "(\\d+)",
                  "@(.+)"
               ]
            }
         },
         "analyzer" : {
            "email" : {
               "tokenizer" : "uax_url_email",
               "filter" : [ "email", "lowercase",  "unique" ]
            }
         }
      }
   }
}

```

当邮箱格式如下时：

```
john-smith_123@foo-bar.com
```

最终处理结果将为：

```
john-smith_123@foo-bar.com, john-smith_123,
john, smith, 123, foo-bar.com, foo, bar, com
```

需要多种模式以允许重复捕获，但也意味着模式不复杂和易于理解。

注意：所有token都以相同的位置处理，并且具有相同的字符偏移量，因此当与突出显示相结合时，**整个原始token将被突出显示，而不仅仅是匹配的子集**。

  例如，查询上述电子邮件地址`"smith",`将会突出显示整个原始token：

```
  <em>john-smith_123@foo-bar.com</em>
```

而非仅高亮smith:

```
  john-<em>smith</em>_123@foo-bar.com
```