String Split в DXL - PullRequest
       47

String Split в DXL

1 голос
/ 25 июня 2009

У меня есть строка

Пример: «Мы предпочитаем вопросы, на которые можно ответить, а не просто обсудить»

Теперь я хочу отделить эту строку от ";" лайк Мы предпочитаем вопросы, на которые можно ответить а также не только обсуждается

возможно ли это в DXL.

Я изучаю DXL, поэтому понятия не имею, можем ли мы разделиться или нет.

Примечание: это не домашняя работа.

Ответы [ 7 ]

3 голосов
/ 17 июля 2009

Если вы разбили строку только один раз, я бы так и сделал:

string s = "We prefer questions that can be answered; not just discussed"

string sub = ";"

int offset

int len

if ( findPlainText(s, sub, offset, len, false)) {

/* the reason why I subtract one and add one is to remove the delimiter from the out put.
 First print is to print the prefix and then second is the suffix.*/

print s[0 : offset -1]

print s[offset +1 :]


} else {
// no delimiter found
print "Failed to match"

} 

Вы также можете использовать регулярные выражения, см. Справочное руководство по DXL. Было бы лучше использовать регулярные выражения, если вы хотите разделить строку по нескольким разделителям, таким как str = "this; is; example"

3 голосов
/ 16 июля 2009

Быстрое соединение и разделение, которые я мог придумать. Швы работать нормально.

int array_size(Array a){
    int size = 0;
    while( !null(get(a, size, 0) ) )
        size++;
    return size;
}

void array_push_str(Array a, string str){
    int array_index = array_size(a);

    put(a, str, array_index, 0);
}

string array_get_str(Array a, int index){
    return (string get(a, index, 0));
}

string str_join(string joiner, Array str_array){
    Buffer joined = create;
    int array_index = 0;

    joined += "";

    for(array_index = 0; array_index < array_size(str_array); array_index++){
        joined += array_get_str(str_array, array_index);
        if( array_index + 1 < array_size(str_array) )
            joined += joiner;
    }

    return stringOf(joined)
}

Array str_split(string splitter, string str){
    Array tokens = create(1, 1);
    Buffer buf = create;
    int str_index;

    buf = "";

    for(str_index = 0; str_index < length(str); str_index++){
        if( str[str_index:str_index] == splitter ){
            array_push_str(tokens, stringOf(buf));
            buf = "";
        }else{
            buf += str[str_index:str_index];
        }
    }
    array_push_str(tokens, stringOf(buf));

    delete buf;
    return tokens;
}
2 голосов
/ 11 июня 2015

Прошу прощения за некрозу этого поста. Будучи новичком в DXL, я провел некоторое время с тем же испытанием. Я заметил, что имеющиеся в наличии реализации имеют разные спецификации для "разбиения" строки. Любя язык Ruby , я пропустил реализацию, которая хотя бы близка к версии Ruby String # split . Может быть, мои выводы будут кому-нибудь полезны.

Вот функциональное сравнение

  • Вариант A: Реализация niol (которая на первый взгляд кажется той же самой реализацией, которая обычно встречается в Capri Soft ,
  • Вариант B: Реализация PJT,
  • Вариант C: Реализация Бретта и
  • Вариант D: моя реализация (которая обеспечивает правильную функциональность imo).

Чтобы устранить структурные различия, все реализации были реализованы в функциях, возвращая список Skip или Array.


Результаты расщепления

Обратите внимание, что все реализации возвращают разные результаты, в зависимости от их определения "расщепления":

строка mellow yellow; разделитель ello

    splitVariantA returns 1 elements: ["mellow yellow" ]
    splitVariantB returns 2 elements: ["m" "llow yellow" ]
    splitVariantC returns 3 elements: ["w" "w y" "" ]
    splitVariantD returns 3 elements: ["m" "w y" "w" ]

строка now's the time; разделитель

    splitVariantA returns 3 elements: ["now's" "the" "time" ]
    splitVariantB returns 2 elements: ["" "now's  the time" ]
    splitVariantC returns 5 elements: ["time" "the" "" "now's" "" ]
    splitVariantD returns 3 elements: ["now's" "the" "time" ]

строка 1,2,,3,4,,; разделитель ,

    splitVariantA returns 4 elements: ["1" "2" "3" "4" ]
    splitVariantB returns 2 elements: ["1" "2,,3,4,," ]
    splitVariantC returns 7 elements: ["" "" "4" "3" "" "2" "" ]
    splitVariantD returns 7 elements: ["1" "2" "" "3" "4" "" "" ]

Сроки

Разделение строки 1,2,,3,4,, с шаблоном , для 10000 раз на моей машине дает следующие значения времени:

    splitVariantA() : 406 ms
    splitVariantB() : 46 ms
    splitVariantC() : 749 ms
    splitVariantD() : 1077 ms

К сожалению, моя реализация D самая медленная. Удивительно, но реализация C регулярных выражений довольно быстрая.


Исходный код

// niol, modified
Array splitVariantA(string splitter, string str){
    Array tokens = create(1, 1);
    Buffer buf = create;
    int str_index;
    buf = "";

    for(str_index = 0; str_index < length(str); str_index++){
        if( str[str_index:str_index] == splitter ){
            array_push_str(tokens, stringOf(buf));
            buf = "";
        } 
        else
            buf += str[str_index:str_index];
    }
    array_push_str(tokens, stringOf(buf));
    delete buf;
    return tokens;
}

// PJT, modified
Skip splitVariantB(string s, string delimiter) {

    int offset  
    int len
    Skip skp = create

    if ( findPlainText(s, delimiter, offset, len, false)) {
        put(skp, 0, s[0 : offset -1])
        put(skp, 1, s[offset +1 :])
    }

    return skp  
}

// Brett, modified
Skip splitVariantC (string s, string delim) {

    Skip skp = create
    int i = 0
    Regexp split = regexp "^(.*)" delim "(.*)$"
    while (split s) {
        string temp_s = s[match 1]
        put(skp, i++, s[match 2])
        s = temp_s
    }
    put(skp, i++, s[match 2])
    return  skp
}

Skip splitVariantD(string str, string pattern) {

    if (null(pattern) || 0 == length(pattern))
        pattern = " ";

    if (pattern == " ")
        str = stringStrip(stringSqueeze(str, ' '));

    Skip result = create;
    int i = 0; // index for searching in str
    int j = 0; // index counter for result array
    bool found = true;

    while (found) {
        // find pattern     
        int pos = 0;
        int len = 0;
        found = findPlainText(str[i:], pattern, pos, len, true);

        if (found) {
            // insert into result
            put(result, j++, str[i:i+pos-1]);
            i += pos + len;
        }
    }
    // append the rest after last found pattern
    put(result, j, str[i:]);

    return result;
}
1 голос
/ 31 мая 2013

ФАКТИЧЕСКИ РАБОТАЕТ:

Это решение будет разделяться столько раз, сколько необходимо, или ни одного, если разделитель не существует в строке.

Это то, что я использовал вместо традиционной команды "split". Фактически он пропускает создание массива и просто перебирает каждую строку, которая будет в массиве, и вызывает «someFunction» для каждой из этих строк.

string s = "We prefer questions that can be answered; not just discussed"

// for this example, ";" is used as the delimiter
Regexp split = regexp "^(.*);(.*)$"

// while a ";" exists in s
while (split s) {

    // save the text before the last ";"
    string temp_s = s[match 1]

    // call someFunction on the text after the last ";"
    someFunction(s[match 2])

    // remove the text after the last ";" (including ";")
    s = temp_s
}

// call someFunction again for the last (or only) string
someFunction(s)

Извините за некрозу старый пост; Я просто не нашел другие ответы полезными.

0 голосов
/ 01 февраля 2019

Вот лучшая реализация. Это рекурсивное разбиение строки путем поиска по ключевому слову.

pragma runLim, 10000
string s = "We prefer questions that can be answered,not just discussed,hiyas;
Next Line,Var1,Nemesis;
Next Line,Var2,Nemesis1;
Next Line,Var3,Nemesis2;
New,Var4,Nemesis3;
Next Line,Var5,Nemesis4;
New,Var5,Nemesis5;"
string sub = "," 
int offset
int len

string searchkey=null
string curr=s
string nxt=s
string searchline=null
string Modulename=""
string Attributename=""
string Attributevalue=""

while(findPlainText(curr,"Next Line", offset,len,false))
{
    int intlen=offset

    searchkey=curr[offset:length(curr)]

    if(findPlainText(searchkey,"Next Line",offset,len,false))
    {
        curr=searchkey[offset+1:length(searchkey)]
    }

    if(findPlainText(searchkey,";",offset,len,false))
    {       
        searchline=searchkey[0:offset]  
    }

    int counter=0
    while(length(searchline)>0)
    {   
        if (findPlainText(searchline, sub, offset, len, false))
        {
            if(counter==0)
            {
                Modulename=searchline[0 : offset -1]
                counter++
            }
            else if(counter==1)
            {
                Attributename=searchline[0 : offset -1]
                counter++
            }
            searchline= searchline[offset+1:length(searchline)]
        }
        else
        {

            if(counter==2)
            {
                Attributevalue=searchline[0:length(searchline)-2]
                counter++
            }
            searchline=""
        }       
    }
    print "Modulename="Modulename " Attributename=" Attributename " Attributevalue= "Attributevalue "\n"
}
0 голосов
/ 29 января 2019

Я попробовал это и сработал для меня ...

string s = "We prefer questions that can be answered,not just discussed,hiyas"

string sub = ","
int offset

int len

string s1=s

while(length(s1)>0){

    if ( findPlainText(s1, sub, offset, len, false)) {

        print s1[0 : offset -1]"\n"

        s1= s1[offset+1:length(s1)]

    }

    else

    {

        print s1

        s1=""

    }

}
0 голосов
/ 01 ноября 2017

Возможно, кому-то тоже пригодится это слитное решение. Он разбивает строку в Skip на основе разделителя, который может иметь длину больше единицы.

Skip splitString(string s1, string delimit)
{
    int offset, len
    Skip splited = create

    while(findPlainText(s1, delimit, offset, len, false))
    {
        put(splited, s1[0:offset-1], s1[0:offset-1])
        s1 = s1[offset+length(delimit):length(s1)-1]
    }


    if(length(s1)>0)
    {
        put (splited, s1, s1)
    }

    return splited
}
...