Tue Feb 25, 2020 3:43 am
Login Register Lost Password? Contact Us


Função STD.Str.Contains talvez não esteja funcionando direit

Fórum em português para questões gerais e suporte relacionados a ECL/HPCC Systems.

Moderator: hwatanuki

Fri Jan 31, 2020 8:03 pm Change Time Zone

Estive utilizando a função STD.Str.Contains com o objetivo de identificar uma substring dentro de uma string mas o resultado não foi conforme o esperado, a função STD.Str.Contains está encontrando resultados em que não só o padrão informado foi encontrado, mas os caracteres individuais em ordens diferentes também.

Para simplificar o problema, suponha que temos um dataset de frutas contendo apenas nomes de frutas como "Apple", "Grape", "Papaya", "Peach", "Pear", "Pineapple", "Raspberry" e outras.

Aplicando a função STD.Str.Contians com o padrão "pe", o que deveria ser retornado?
1) Grape, Peach, and Pear
2) Apple, Grape, Peach, Pear, Pineapple, Raspberry

E para o padrão "pp"?

Verifique a resposta aqui: http://10.173.248.1:8010/esp/files/stub ... 128-144013

A função de fato deveria procurar pela presença de cada caractére da string ou encontrar todo o padrão/substring dentro da string?

Dê uma olhada em outro exemplo do uso dessa função na tentantiva de encontrar uma string que contenha a substring "HANDGUN": http://10.173.248.1:8010/esp/files/stub ... 128-134352

Especialmente as linhas 3, 7, 9, 10, 11, 12, 14 ...
Hellesandro
 
Posts: 2
Joined: Fri Jan 31, 2020 7:15 pm

Mon Feb 03, 2020 2:50 pm Change Time Zone

Hellesandro,

The Contains function's documentation says:
The Contains functions return true if all the characters in the pattern appear in the source, otherwise they return false.
so it will return every fruit that contains all the specified letters, in any order.

Here's the way I tested it for your scenario:
Code: Select all
IMPORT Std;
s := ['Apple', 'Grape', 'Papaya', 'Peach', 'Pear', 'Pineapple', 'Raspberry' ];
ds := DATASET(s,{STRING w});

ds(Std.Str.Contains(w,'pe',0));  //Apple,Grape,Pineapple,Raspberry
ds(Std.Str.Contains(w,'pe',1));  //Apple,Grape,Peach,Pear,Pineapple,Raspberry
ds(Std.Str.Contains(w,'per',0)); //Grape,Raspberry
ds(Std.Str.Contains(w,'per',1)); //Grape,Pear,Raspberry

IOW, this function is not looking for patterns, just the presence of all characters. If you need to look for specific patterns, then you should look at using regular expressions (like the REGEXFIND and REGEXREPLACE functions) or use ECL's PARSE technology.

HTH,

Richard
rtaylor
Community Advisory Board Member
Community Advisory Board Member
 
Posts: 1519
Joined: Wed Oct 26, 2011 7:40 pm

Mon Feb 03, 2020 5:52 pm Change Time Zone

Olá Hellesandro,

Somente reforçando o que o Richard comentou acima, a função STD.str.Contains retorna um valor booleano que será TRUE toda vez que TODOS os caracteres fornecidos como segundo parâmetro da função forem detectados na STRING especificado no primeiro parâmetro da função, independentemente da ordem ou posição desses caracteres.

No caso de um código como:

Code: Select all
IMPORT STD;

dFruitNFamily := DATASET([{'Apple'}, {'Apricot'}, {'Avocado'}, {'Banana'},
                                                                                                                                                                                {'Blackcurrant'}, {'Blackberry'}, {'Blueberry'}, {'Cherry'},
                                                                                                                                                                                 {'Coconut'}, {'Fig'}, {'Grape'}, {'Kiwi Fruit'}, {'Lemon'}, {'Lime'},
                                                                                                                                                                                {'Lychee'}, {'Mango'}, {'Nectarine'}, {'Orange'}, {'Papaya'},
                                                                                                                                                                                {'Passion Fruit'}, {'Peach'}, {'Pear'}, {'Pineapple'}, {'Plum'},
                                                                                                                                                                                {'Quince'}, {'Raspberry'}, {'Strawberry'}, {'Watermelon'}],
                                                                                                                                                                                {STRING Name});

OUTPUT(dFruitNFamily(STD.Str.Contains(Name, 'pe', true)),, NAMED('Contains_pe'));
OUTPUT(dFruitNFamily(STD.Str.Contains(Name, 'pp', true)),, NAMED('Contains_pp'));



A primeira saída retornará todos os registros do dataset dFruitNFamily que contêm simultaneamente os caracteres "p" e "e" ou "P" e "e" ou "p" e "E" ou "P" e "E" no campo Name, tais como 'Apple', 'Grape', 'Peach', 'Pineapple' e 'Raspberry'.
A segunda saída retornará todos os registros do dataset dFruitNFamily que contêm simultaneamente os caracteres "p" e "p" ou "p" e "P" ou "P" e "P" no campo Name, tais como 'Apple', 'Papaya', 'Pineapple'.

Para o seu objetivo original, uma alternativa seria usar a função STD.Str.WildMatch. Por exemplo, na primeira saída, você poderia usar:
Code: Select all
OUTPUT (dFruitNFamily (STD.Str.WildMatch (Name, '* pe *', true)) ,, NAMED ('Contains_pe'));


Espero ter ajudado a esclarecer o uso dessa função.

Hugo Watanuki
hwatanuki
 
Posts: 6
Joined: Mon Apr 15, 2019 1:22 am

Tue Feb 04, 2020 6:00 pm Change Time Zone

Obrigado pela resposta!
Hellesandro
 
Posts: 2
Joined: Fri Jan 31, 2020 7:15 pm


Return to Português

Who is online

Users browsing this forum: No registered users and 1 guest