» »

Kako se lotit case insensitive "find and replace"?

Kako se lotit case insensitive "find and replace"?

HotBurek ::

Dobro jutro.


Problem je zelo preprost.

string = "Set manjših pravokotnih vakuumskih posod, 5-delni set";
input = "set";


In sedaj bi rad naredil, kot piše v naslovu, case insensitive find and replace.

Besedo "set" na koncu string ni težko zamenjat. Kako naj zamenjam besedo "Set" na začetku, da hkrati ohranim zapis z veliko začetnico?

Ugibam, da je ena možnost, da dam string v lower, potem iščem če se kje beseda pojavi, in v kolikor se, uporabim indeks kje se to pojavi, potem pa na tistem indeksu preberem string in naredim replace.
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
  • spremenilo: HotBurek ()

HotBurek ::

Evo, je nekako uspelo.

Sem naredil tako:
- da iz stringa naredi besede (split by " ")
- prav tako iz input-a naredi split po presledku, ter besede razvrsti od najdaljše do najkrajše, ter izloči podvojene
- potem pa gre za vsako besedo v string, in loop po vsaki besedi iz inputa, oboje ko primerja da v lower, in če najde match, naredi "replace", sicer pa kar z obstoječo prepiše

Prototip kode:

import re;

string_in = "Set manjših pravokotnih vakuumskih posod, 5-delni set";

print("string_in=" + string_in);

input = "set delni vakuum kot delni";

print("input=" + input);

string_out = "";

items = [];

items = input.split(" ");

items = sorted(items, key=len, reverse=True);

items = list(dict.fromkeys(items));

print("items=" + str(items));

string_items = string_in.split(" ");

for i in range(0, len(string_items)):

    found = False;

    for j in range(0, len(items)):

        match = re.search(items[j].lower(), string_items[i].lower());

        if match != None:

            string_out = string_out + string_items[i][0:match.start()] + "<span>" + string_items[i][match.start():match.end()] + "</span>" + string_items[i][match.end():] + " ";

            found = True;
            break;

    if found == False:

        string_out = string_out + string_items[i] + " ";

string_out = string_out.strip();

print("string_out=" + string_out);


Output:

string_in=Set manjših pravokotnih vakuumskih posod, 5-delni set
input=set delni vakuum kot delni
items=['vakuum', 'delni', 'set', 'kot']
string_out=<span>Set</span> manjših pravo<span>kot</span>nih <span>vakuum</span>skih posod, 5-<span>delni</span> <span>set</span>
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

Zgodovina sprememb…

  • spremenilo: HotBurek ()

mr_chai ::

Če te skrbi samo velika začetnica, pol lahko preprosto kličeš capitalize() po končanem replace-u na downcasanem stringu, če se mora case ohranjat po vseh besedah v stavku , je pa druga zgodba.

Ampak mislim, da se to vse da z regexom. Tu je en podoben problem

https://stackoverflow.com/questions/288...

Zgodovina sprememb…

  • spremenilo: mr_chai ()

AndrejS ::

string.Replace("set", "xxx", System.StringComparison.InvariantCultureIgnoreCase);

Spura ::

To ponavadi naredis z regexom in pogledas kaj je bilo matchan in prilagodis replace.

HotBurek ::

Dobro jutro.

Tole je končna verzija, skupaj z komentarji, če bo koga zanimalo.

def make_it_happen(input_string, search_query):

    # set output
    output_string = "";

    # split search_query by space
    search_query_items_temp = search_query.split(" ");

    # order search query items by string length from longest to shortest
    search_query_items_temp = sorted(search_query_items_temp, key=len, reverse=True);

    # remove duplicates
    search_query_items_temp = list(dict.fromkeys(search_query_items_temp));

    # make empty list for final search query items
    search_query_items_final = [];

    # go throug search query items and make sure to not add string with length 0
    for i in range(0, len(search_query_items_temp)):

        if len(search_query_items_temp[i]) > 0:
            search_query_items_final.append(search_query_items_temp[i]);

    # split input string by space
    input_string_items = input_string.split(" ");

    # go for each input string item
    for i in range(0, len(input_string_items)):

        found = False;

        # go trhoug each search query item
        for j in range(0, len(search_query_items_final)):

            match = re.search(search_query_items_final[j].lower(), input_string_items[i].lower());

            # if there is match
            if match != None:

                output_string = output_string + input_string_items[i][0:match.start()] + "<span>" + \
                         input_string_items[i][match.start():match.end()] + "</span>" + \
                         input_string_items[i][match.end():] + " ";

                # set found to true and break
                found = True;
                break;

        if found == False:

            # if not found just append input item to output item
            output_string = output_string + input_string_items[i] + " ";

    # strip spaces
    output_string = output_string.strip();

    # return output
    return output_string;


Primer:
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window

mr_chai ::

Zakaj kompliciraš no ? :D Vse kar rabiš je, da dodaš case insensitive opcijo v tvoj regex!

Zgodovina sprememb…

  • spremenilo: mr_chai ()

mr_chai ::

Nisem nikoli delu v Pythonu a z nekaj brskanja po dokumnetaciji sem našel string replace. Evo tole je 90% rešitve, ostalo dodaš sam.




Edit: Sm opazu, da očitno matcha tudi span in pol ovije že obstoječi span s spanom ;) Popravit treba regex. Jaz sem že zaprl online IDE. Boš sam...

Zgodovina sprememb…

  • spremenilo: mr_chai ()

Dane0 ::

mr_chai je izjavil:

Nisem nikoli delu v Pythonu a z nekaj brskanja po dokumnetaciji sem našel string replace. Evo tole je 90% rešitve, ostalo dodaš sam.




Edit: Sm opazu, da očitno matcha tudi span in pol ovije že obstoječi span s spanom ;) Popravit treba regex. Jaz sem že zaprl online IDE. Boš sam...


re je the way to go ja, ostalo je odkrivanje tople vode in povsem nepotrebno kompliciranje:)


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

python regex split

Oddelek: Programiranje
7551 (456) HotBurek
»

python -slovar

Oddelek: Programiranje
223124 (2103) Valex86
»

[Ajax in Java] v IE6 dela, v Firefoxu ne

Oddelek: Programiranje
241913 (1667) krho
»

[C++-Qt] QDateTime v LocalDate in LocalTime formatu

Oddelek: Programiranje
101183 (1075) 'FireSTORM'
»

[C#] Mnozenje

Oddelek: Programiranje
61543 (1385) noraguta

Več podobnih tem