Фильтр символов Pattern replace
Фильтр символов pattern_replace использует регулярное выражение для поиска символов, которые следует заменить указанной строкой замены. Строка замены может ссылаться на группы захвата в регулярном выражении.
Будьте осторожны с патологическими регулярными выражениями
Фильтр символов pattern replace использует регулярные выражения Java.
Неправильно составленное регулярное выражение может работать очень медленно или даже сгенерировать ошибку StackOverflowError и привести к внезапному завершению работы узла.
Подробнее о патологических регулярных выражениях и способах их избежания.
Настройка
Фильтр символов pattern_replace принимает следующие параметры:
| | Регулярное выражение Java. Обязательно. |
| | Строка замены, которая может ссылаться на группы захвата, используя синтаксис |
| | Флаги регулярных выражений Java флаги. Флаги должны быть разделены символом "|", например |
Пример конфигурации
В этом примере мы настраиваем фильтр символов pattern_replace для замены вставленных дефисов в числах на нижние подчеркивания, т.е 123-456-789 → 123_456_789:
resp = client.indices.create(
index="my-index-000001",
settings={
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "standard",
"char_filter": [
"my_char_filter"
]
}
},
"char_filter": {
"my_char_filter": {
"type": "pattern_replace",
"pattern": "(\\d+)-(?=\\d)",
"replacement": "$1_"
}
}
}
},
)
print(resp)
resp1 = client.indices.analyze(
index="my-index-000001",
analyzer="my_analyzer",
text="My credit card is 123-456-789",
)
print(resp1) response = client.indices.create(
index: 'my-index-000001',
body: {
settings: {
analysis: {
analyzer: {
my_analyzer: {
tokenizer: 'standard',
char_filter: [
'my_char_filter'
]
}
},
char_filter: {
my_char_filter: {
type: 'pattern_replace',
pattern: '(\\d+)-(?=\\d)',
replacement: '$1_'
}
}
}
}
}
)
puts response
response = client.indices.analyze(
index: 'my-index-000001',
body: {
analyzer: 'my_analyzer',
text: 'My credit card is 123-456-789'
}
)
puts response const response = await client.indices.create({
index: "my-index-000001",
settings: {
analysis: {
analyzer: {
my_analyzer: {
tokenizer: "standard",
char_filter: ["my_char_filter"],
},
},
char_filter: {
my_char_filter: {
type: "pattern_replace",
pattern: "(\\d+)-(?=\\d)",
replacement: "$1_",
},
},
},
},
});
console.log(response);
const response1 = await client.indices.analyze({
index: "my-index-000001",
analyzer: "my_analyzer",
text: "My credit card is 123-456-789",
});
console.log(response1); PUT my-index-000001
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "standard",
"char_filter": [
"my_char_filter"
]
}
},
"char_filter": {
"my_char_filter": {
"type": "pattern_replace",
"pattern": "(\\d+)-(?=\\d)",
"replacement": "$1_"
}
}
}
}
}
POST my-index-000001/_analyze
{
"analyzer": "my_analyzer",
"text": "My credit card is 123-456-789"
} Вышеприведенный пример генерирует следующие термины:
[ My, credit, card, is, 123_456_789 ]
Использование строки замены, изменяющей длину исходного текста, будет работать для целей поиска, но приведет к некорректным выделениям, как показано в следующем примере.
В этом примере вставляется пробел всякий раз, когда встречается строчная буква, за которой следует заглавная буква (т.е. fooBarBaz → foo Bar Baz), позволяя словам camelCase искать отдельные слова:
resp = client.indices.create(
index="my-index-000001",
settings={
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "standard",
"char_filter": [
"my_char_filter"
],
"filter": [
"lowercase"
]
}
},
"char_filter": {
"my_char_filter": {
"type": "pattern_replace",
"pattern": "(?<=\\p{Lower})(?=\\p{Upper})",
"replacement": " "
}
}
}
},
mappings={
"properties": {
"text": {
"type": "text",
"analyzer": "my_analyzer"
}
}
},
)
print(resp)
resp1 = client.indices.analyze(
index="my-index-000001",
analyzer="my_analyzer",
text="The fooBarBaz method",
)
print(resp1) response = client.indices.create(
index: 'my-index-000001',
body: {
settings: {
analysis: {
analyzer: {
my_analyzer: {
tokenizer: 'standard',
char_filter: [
'my_char_filter'
],
filter: [
'lowercase'
]
}
},
char_filter: {
my_char_filter: {
type: 'pattern_replace',
pattern: '(?<=\\p{Lower})(?=\\p{Upper})',
replacement: ' '
}
}
}
},
mappings: {
properties: {
text: {
type: 'text',
analyzer: 'my_analyzer'
}
}
}
}
)
puts response
response = client.indices.analyze(
index: 'my-index-000001',
body: {
analyzer: 'my_analyzer',
text: 'The fooBarBaz method'
}
)
puts response const response = await client.indices.create({
index: "my-index-000001",
settings: {
analysis: {
analyzer: {
my_analyzer: {
tokenizer: "standard",
char_filter: ["my_char_filter"],
filter: ["lowercase"],
},
},
char_filter: {
my_char_filter: {
type: "pattern_replace",
pattern: "(?<=\\p{Lower})(?=\\p{Upper})",
replacement: " ",
},
},
},
},
mappings: {
properties: {
text: {
type: "text",
analyzer: "my_analyzer",
},
},
},
});
console.log(response);
const response1 = await client.indices.analyze({
index: "my-index-000001",
analyzer: "my_analyzer",
text: "The fooBarBaz method",
});
console.log(response1); PUT my-index-000001
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "standard",
"char_filter": [
"my_char_filter"
],
"filter": [
"lowercase"
]
}
},
"char_filter": {
"my_char_filter": {
"type": "pattern_replace",
"pattern": "(?<=\\p{Lower})(?=\\p{Upper})",
"replacement": " "
}
}
}
},
"mappings": {
"properties": {
"text": {
"type": "text",
"analyzer": "my_analyzer"
}
}
}
}
POST my-index-000001/_analyze
{
"analyzer": "my_analyzer",
"text": "The fooBarBaz method"
} Вышеприведенное возвращает следующие термины:
[ the, foo, bar, baz, method ]
Поиск bar найдет документ правильно, но выделение результата будет некорректным, так как наш фильтр символов изменил длину исходного текста:
resp = client.index(
index="my-index-000001",
id="1",
refresh=True,
document={
"text": "The fooBarBaz method"
},
)
print(resp)
resp1 = client.search(
index="my-index-000001",
query={
"match": {
"text": "bar"
}
},
highlight={
"fields": {
"text": {}
}
},
)
print(resp1) response = client.index(
index: 'my-index-000001',
id: 1,
refresh: true,
body: {
text: 'The fooBarBaz method'
}
)
puts response
response = client.search(
index: 'my-index-000001',
body: {
query: {
match: {
text: 'bar'
}
},
highlight: {
fields: {
text: {}
}
}
}
)
puts response const response = await client.index({
index: "my-index-000001",
id: 1,
refresh: "true",
document: {
text: "The fooBarBaz method",
},
});
console.log(response);
const response1 = await client.search({
index: "my-index-000001",
query: {
match: {
text: "bar",
},
},
highlight: {
fields: {
text: {},
},
},
});
console.log(response1); PUT my-index-000001/_doc/1?refresh
{
"text": "The fooBarBaz method"
}
GET my-index-000001/_search
{
"query": {
"match": {
"text": "bar"
}
},
"highlight": {
"fields": {
"text": {}
}
}
} Вывод из приведенного выше примера:
{
"timed_out": false,
"took": $body.took,
"_shards": {
"total": 1,
"successful": 1,
"skipped" : 0,
"failed": 0
},
"hits": {
"total" : {
"value": 1,
"relation": "eq"
},
"max_score": 0.2876821,
"hits": [
{
"_index": "my-index-000001",
"_id": "1",
"_score": 0.2876821,
"_source": {
"text": "The fooBarBaz method"
},
"highlight": {
"text": [
"The foo<em>Ba</em>rBaz method"
]
}
}
]
}
} | Обратите внимание на некорректное выделение. |
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/analysis-pattern-replace-charfilter.html