NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Ladislav Niderle:7.5.2020 8:46

Ahoj, potřeboval bych poradit jak zjistit jestli posílaný text má v sobě nějaké diakritické znaménko. Jedná se o to, že aplikace bude posílat SMS a uživatel by rád viděl kolik mu to pošle celkem SMSek. Znám pravidla, ale nejsem momentálně schopen nijak zjistit, zda text, který budu posílat obsahuje nějaká diakritika.

Zkusil jsem: Snažil jsem se použít nějakým způsobem regulární výraz, ale nebyl jsem moc úspěšný, jelikož jsem musel vyjmenovávat včechny znaménka a věřím, že to přitom jde určitě jednodušeji.

Chci docílit: Snaha je docílit informovanosti uživatele o skutečném počtu odesílaných SMSek.

Předem moc děkujiu za radu.

 
Odpovědět
7.5.2020 8:46
Avatar
Jindřich Máca
Tvůrce
Avatar
Odpovídá na Ladislav Niderle
Jindřich Máca:7.5.2020 10:38

Ahoj a jak přesně by sis to představoval? :D

Když jsi ten problém trochu rozebereš, tak máš v podstatě nějaký text, který obsahuje nějaké znaky a ty chceš zjistit, jestli jsou to znaky z nějaké konkrétní skupiny a případně kolik jich je. Takže nemáš moc na výběr než to vzít znak po znaku a porovnávat ho s tou dotyčnou skupinou, která Tě zajímá.

Z toho plyne následující:

  1. Musíš nějak definovat tu skupinu
  2. Musíš napsat algoritmus pro to porovnávání

A teď se trochu liší konkrétní postupy, jaké můžeš zvolit. Mě napadají asi 3 řešení:

  • Definuješ pole těch znaků a budeš v cyklu zkoumat, jestli znak z toho textu leží v tom poli.
  • To samé jako před tím, ale pomocí regulárního výrazu (to není nic jiného, než automatizace operací s textem za využití nějaké gramatiky).
  • Můžeš zkusit definovat ty znaky pomocí intervalů na úrovni převodu znaků do jejich číselné podoby např. můžeš znát základní ASCII tabulku. A pak se můžeš opět ptát, jestli ta číselná reprezentace toho znaku z textu leží v daném intervalu. Tady bych se ale trochu bál rozdílné číselné reprezentace znaků s diakritikou v různých znakových sadách.

Tohle je tedy nějaký nástřel různých způsobů, jak to řešit, třeba Tě napadne ještě nějaký jiný, ale základní princip bude pořád stejný. :)

 
Nahoru Odpovědět
7.5.2020 10:38
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:7.5.2020 11:13

https://mlich.zam.slu.cz/wys4.htm
Mam tam kod na odstraneni diakritiky. Staci si to jen upravit.

function patternReplace(reg,repl,str)
{
//reg[0] = reg[0].replace(/([\!\$\(\)\*\+\.\/\:\=\?\[\\\]\^\{\|\}])/g,"\\$0");
reg = new RegExp(reg[0],reg[1]);
//alert(str)
alert(reg.test(str) ? "Match" : "No match");
return str.replace(reg,repl);
}

function odstranDiakritiku(str1)
{
var i,j, str2;
str2 = '';
for(i = 0; i < str1.length; i++)
        {
        j = DIAKRITIKA[0].indexOf(str1.charAt(i));
        if (j!==-1)
                {
                str2 += DIAKRITIKA[1].charAt(j);
                }
        else    {
                str2 += str1.charAt(i);
                }
        }
return str2;
}

function textToFileName(str)
{
return odstranDiakritiku(str).toLowerCase().replace(new RegExp('[^a-z0-9]+','g'),'_').replace(new RegExp('(^_)|(_$)','g'),'');
}

var DIAKRITIKA = [
"áäčďéěíĺľňóôöŕšťúůüýřžÁÄČĎÉĚÍĹĽŇÓÔÖŔŠŤÚŮÜÝŘŽ",
"aacdeeillnooorstuuuyrzAACDEEILLNOOORSTUUUYRZ"
];
Editováno 7.5.2020 11:14
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
7.5.2020 11:13
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:7.5.2020 11:17

A bylo by to rychlejsi, kdybys ten cyklus napsal takto:

var i,j, str2, end;
str2 = '';
end = str1.length;
for(i = 0; i < end; i++)
 
Nahoru Odpovědět
7.5.2020 11:17
Avatar

Člen
Avatar
:8.5.2020 10:44

Ja by som len k Petrovmu kódu dodal, že na prevod, na nahrádzanie znakov je tu regex funkcia replace vďaka ktorej ide výmenu znakov napísať jednoducho, krátko, zrozumiteľne a bez cyklov:

const latin_map = {
  'á': 'a',
  'Á': 'A',
  'ä': 'a',
  'Ä': 'A',
  'å': 'a',
  'Å': 'A',
  /* atď */
}

function toBasicLatin (str, map) {
  return str.replace(/[^A-Za-z]/g, x => map[x] || x)
}

/* test */
console.log(toBasicLatin('ÅpätÁr', latin_map)) // vypíše ApatAr
Editováno 8.5.2020 10:45
 
Nahoru Odpovědět
8.5.2020 10:44
Avatar

Člen
Avatar
:8.5.2020 12:05

Ešte by som dodal, že štandard Unicode má definovanú tabuľku pre dekompozíciu znakov s diakritikou. A JS má novú metódu na normalizáciu stringov podľa tejto tabuľky. Pomocou tejto dekompozície, čiže rozdelení znakov s diakritikou na znaky bez diakritiky a zvlášť diakritické znamienka, a pomocou následného vymazania iba týchto diakritických znamienok, ide napísať univerzálna funkcia na odstránenie diakritiky z textov:

function toBasicLatin (str) {
  return str
    .normalize('NFD')
    .replace(/[\u0300-\u036F]/g, '')
}

console.log(toBasicLatin('ĀçõĎżűşęï')) // vypíše AcoDzusei

Čo sa týka kompatibility, tá je uvedená TU

 
Nahoru Odpovědět
8.5.2020 12:05
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 6 zpráv z 6.