Készítettem egy RegEx-et, működik is: ^\+36((1|20|30|31|70)\d{7}|(?!(1|20|30|31|70))\d{2}\d{6})$
Kérdés, lehet-e optimalizálni vagy a (?!...) részt átírva jobb-e a ^\+36((1|20|30|31|70)\d{7}|[^(1|20|30|31|70)]{2}\d{6})$ kifejezés?
- 7337 megtekintés
Hozzászólások
20|30|70 => [237]0
\d{2}\d{6} => \d{8}
t
- A hozzászóláshoz be kell jelentkezni
+1
\d{2}\d{6} az olvashatóságért maradt bent, egyébként jogos.
[237]0 nem lassít az eredeti helyett?
Egyik fórumban arról olvastam, nagyban nyelvfüggő, melyikben hogyan programozták le a RegEx engine-t. :-/
- A hozzászóláshoz be kell jelentkezni
Érzésre szerintem gyorsabb, mert a | nál többet kell vizsgálnia, mint 1 karakter.
- A hozzászóláshoz be kell jelentkezni
Szerintem rendes regex lib esetén pont ugyanaz lesz a végeredmény. Ugyanis egy végesautomatává kell fordulnia a kifejezésnek, az pedig meg fog egyezni.
- A hozzászóláshoz be kell jelentkezni
Az 1-esre pedig nincs szükség külön, hisz 1 + 7 jegy ugyanannyi, mint 2 + 6
- A hozzászóláshoz be kell jelentkezni
Valamelyikünk félreérti. 1-est Budapest miatt kell megkülönböztetni. Akkor 7 további számjegyre van szükség. Második regex második részére utalsz? Az olyan két számjegyet ír elő, ami nem 1-essel kezdődik és hat másik követi. Bár ahogy nézem ez kizárja a 10-19 körzeteket. :( Mindjárt megnézem tesztelőben.
- A hozzászóláshoz be kell jelentkezni
De mi a különbség a
+36 1 1234567 és
+36 11 234567 között? semmi. Felesleges megkülönböztetni. A BP-i számokat lehet úgy is venni, hogy 10-19-es köretszámok + 6 jegy mint ahogy máshol.
- A hozzászóláshoz be kell jelentkezni
Ill akkor lehet csak gond, ha a BP-i 1-es után nem lehet 0, de ezt a te regexed sem kezelte, én csak azzal kompatibiliset mondtam.
- A hozzászóláshoz be kell jelentkezni
Érvelésed jogos, de ha átírtam ^\+36((31|[237]0)\d{7}|[^(31|[237]0)]{2}\d{6})$ -re, akkor se a bp-i, se a 1x körzetek nem mennek.
- A hozzászóláshoz be kell jelentkezni
Nekem igazából már az eredeti sem megy.
Eredeti: ^\+36((1|20|30|31|70)\d{7}|[^(1|20|30|31|70)]{2}\d{6})$
Picit javítva: ^\+36((1|20|30|31|70)\d{7}|[^(1|20|30|31|70)]\d{2}\d{6})$
Szóval sztem ezek nem jók.
Bocs, vmit elnéztem, ezt még vizsgálom
Na megvan, itt a nem pesti és nem mobilok nem mennek nekem
A te regexedre
^\+36((31|[237]0)\d{7}|[^(31|[237]0)]{2}\d{6})$
Pedig expected end of string at position 45-öt kapok
- A hozzászóláshoz be kell jelentkezni
Tehát rövidségben eddig a ^\+36((31|[237]0)\d{7}|(?!(31|[237]0))\d{2}\d{6})$ a nyerő. Persze performanciában lehet jobb kifejtve a 20-30-70
Ha más formában is le tudod írni és szeretnéd írhatok rá egy kis proggit, ami "megméri" melyik a gyorsabb pár 10-100 ezer random generált telefonszámra.
- A hozzászóláshoz be kell jelentkezni
Mármint [^...] formába? Mert a (?!...) lehetőséget nem tudom, támogatják-e széleskörűen.
- A hozzászóláshoz be kell jelentkezni
Nekem a (?!...) működött és a [^...] nem
The Regex Coach-csal néztem
- A hozzászóláshoz be kell jelentkezni
+1 [^...] mégsem működik rendesen, helyes számokra sincs egyezés.
- A hozzászóláshoz be kell jelentkezni
Kevered a (negált) karakterlistát a vagylagos részkifejezéssel.
Ennek ugyan van jelentése, de nem valószínű, hogy az, amit tulajdonítani szeretnél neki:
[^(31|[237]0)]
Egyébként tanácsos kanonizálni, hogy mivel akarjátok meghajtani azt a reguláris kifejezést, mert anélkül végtelen "nekem megy - érdekes, nekem meg nem" dialógus lesz a topic.
- A hozzászóláshoz be kell jelentkezni
Utóbbi regex motor függő lehet. Egyikkel nekem zárójelezési hibát ad. Másikkal szépen működik.
- A hozzászóláshoz be kell jelentkezni
Tényleg semmi, mert egyik sem valid hívószám: Bp.-en nincs 1-gyel kezdődő hívószám, illetve kétjegyű körzetszám nem kezdődhet 1-gyel. Ha mindenképp le akarod választani a körzetszámot, akkor 1-gyel kezdődő esetben 1+7, nem 1-gyel kezdődő esetben meg 2+6 jegyre kell bontani a számot.
- A hozzászóláshoz be kell jelentkezni
Oké, de nyilván érted mit mondtam... Az első hozzászólásban lévő regex is elfogadja a BPi 1-gyel kezdődő számokat, de jó, akkor legyen
+36 1 2345678 és
+36 12 345678
Ezért felesleges (ha nem akarunk teljesen pontos ellenőrzést csinálni) külön vizsgálni a BPi és nem BPi számokat.
Én csak a kérdésre válaszoltam, nem néztem, hogy mi az a szám amit még el kéne fogadnia. Pl a 38 és 50-es körzetek is 7 jegyűek, a 71-es pedig 10. És egy csomó körzetszám nem is létezik. Én bevallom ezeket nem tudtam, nem is figyeltem rá, de akinek fontos, az úgyis rákeres az interneten.
- A hozzászóláshoz be kell jelentkezni
Ha lehet kék is, zöld is, meg macska is, akkor mit ellenőrzöl illetve minek? :)
- A hozzászóláshoz be kell jelentkezni
Erre azt hiszem a kérdező már megadta a választ: "Másrészt nem nekem kell eldönteni hogy valós-e a szám (létezik-e ténylegesen adott körzetszám), mert azt előzőleg ellenőrizték már. Nekem csak annyi kell, megfelel-e egy általános mintának a szám (nem írták-e el felvitelkor). Mobilnál és bp-i számnál legyen 7 további számjegy az előfizető azonosítására, míg egyéb körzetszámoknál hat darab számjegy."
Szóval ha ő azt mondja, hogy elég, ha a számjegyek száma stimmel BPi számok esetén, akkor mért kérdőjelezed meg a szándékát?
Az általam írt példa tényleg rossz volt, de a hangsúly nem az 1-es körzetszám utáni 1-esen volt, lehetett volna ott bármi más, úgyhogy nem érzem jogosnak, hogy abba kötöttél bele.
- A hozzászóláshoz be kell jelentkezni
Most mégis közétek "lövök". Elírás lehet nem létező körzetszám felvitele is. Egy pontosabb, de lassabb megoldás: ^\+36((1|20|21|30|31|50|70)[1-9]\d{6}|((2[23456789])|(3[234567])|(4[02456789])|(5[234679])|(6[23689])|(7[23456789])|(8[02345789])|(9[01234569]))[1-9]\d{5})$
Ezt majd egyszerűsítem, ha megéri.
- A hozzászóláshoz be kell jelentkezni
Mi lesz a +3680000000 számmal?
- A hozzászóláshoz be kell jelentkezni
Van listád arról, Bp számok milyen mintát követnek? Abból indultam ki, telefonszámok nem kezdődnek nullával. De 1-el sem, legalábbis Bp-en?
- A hozzászóláshoz be kell jelentkezni
Per pillanat nincs a birtokomban aktuális számozási terv, de emlékeim szerint a hét, illetve vidéken hatjegyűre váltás után nem kezdődhettek a hívószámok egyes számmal. Valid telefonszámok (nagyjából átgondolva a számozást):
-ha 9 jegyű, akkor 20, 30, vagy 70 az első két jegy, és a 3. jegy pedig nagyobb, mint egy.
-nyolc jegyű, és az első jegy 1, akkor a második nagyobb, mint egy.
-nyolc jegyű, az első nagyobb, mint egy, a második nem nulla, a harmadik nagyobb, mint egy.
-nyolc jegyű, és a második jegy 0, és az elsőn 4, 5, 8, vagy 9. (A 20, 30, 70 hibás mobil, 60 megszűnt NMT (W450))
A nyolcnál kevesebb számjegy ha jól tudom, 3, 4, vagy 5 jegy esetén lehet valid.
De tényleg egyszerűbb, ha a valid körzetszámok benne vannak egy táblázatban, aztán az és az adott körzetszámhoz tartozó valid hívószámok hossza és a "hívószám első jegye nem lehet 1" alapján vizsgálod a számokat.
- A hozzászóláshoz be kell jelentkezni
Ez a szabály a földrajzi és mobil számokra igaz.
A listákat innen tudod letölteni: http://webpub-ext.nmhh.hu/aga/common/setLanguageAction.do?lang=hu
Azért dumálok annyit, mert tényleg listák, amiket lehet visszafelé algoritmizálni. Aztán van olyan is, amiket még nekem sem sikerült.
Szerintem azon küzdesz, hogy olyan számokat validáljál, amely végén ember van. Ezek a számok is leírhatók listában:
11999999 - invalid
19999999 - valid
22199999 - invalid
22999999 - valid
...
Ebben egy seek >= megmondja, hogy valid vagy invalid.
De ha berakod a
51999999 - Internet hozzáférési szolgáltatás
80999999 - zöld szám
rekordot, akkor azt is tudod. Stb...
- A hozzászóláshoz be kell jelentkezni
Akkor inkább innen, egyben: http://webpub-ext.nmhh.hu/aga_xml
- A hozzászóláshoz be kell jelentkezni
^\+36(?:70|[23][01]|\d)\d{7}$
Ennél rövidebben nem tudom.
A dolog trükkje, hogy az alternation definíció szerint az első találatig megy, nincs backtrack. Így a zárójeles kifejezés a 20, 21, 30, 31, 70 körzetek esetén a körzetszámot, egyébként a körzetszám első számjegyét adja vissza (ami Budapest esetében maga a körzetszám).
A dologgal egyébként elvi problémám van: mi értelme ilyen szinten ellenőrizni? Ha már ezt csinálod, arra is tesztelni kéne, hogy az adott körzetszám létezik-e, illetve értelmes-s. (Ha pl. ügyfél telefonszámát kéred be, az 51 biztos nem lesz jó, pedig valós körzetszám.)
- A hozzászóláshoz be kell jelentkezni
Ez nálam elfogadja a +3620123456-ot és a +36211234567-et is, noha egyiket sem kéne.
- A hozzászóláshoz be kell jelentkezni
Bevallom, én nem teszteltem :) Mivel nézted? (A második számot el kell fogadnia, a 21-es számok hétjegyűek.)
- A hozzászóláshoz be kell jelentkezni
Ok, ezt nem tudtam, az eredeti leírásban csak 20,30,31 és 70 volt:)
The Regex Coach-csal néztem, de nem hiszem, hogy ez lenne a gond. Most megnéztem ezen az online regex tester oldalon is: http://regexpal.com/
Szintén elfogadja.
- A hozzászóláshoz be kell jelentkezni
Basszus, kimaradt a nagyobbjel, így illeszkedés hiányában mégis lesz backtrack...
^\+36(?>[23][01]|70|\d)\d{7}$
- A hozzászóláshoz be kell jelentkezni
Ha elmondanád saját szavaiddal, hogy mit szeretnél elérni, akkor megmondom hogyan kell csinálni. :)
- A hozzászóláshoz be kell jelentkezni
Ha nem látszik az eredeti kiírásból, akkor nem tudod megcsinálni. :)
- A hozzászóláshoz be kell jelentkezni
Aggódásod megható, de én már rég megcsináltam. Csak úgy, hogy még működik is. ;)
Arra utalék. Vala.
Ezek a regexpek nem írnak le Magyarországon használatos hívószámokat, tehát rosszak.
Felesleges gyorsítani őket, mivel ez a módszer igen lassú.
Ha ez valamilyen iskolai feladat, akkor biztosan regexp használata a cél.
Ha meg dolgozni szeretnél vele, azt másképp kell tenni!
Gondoltam segítek...
- A hozzászóláshoz be kell jelentkezni
Mosoly jellel írtad és én is a választ. Gyorsítani nem nagyon akartam és nem iskolai feladat. De legalább elismerted hogy nagyon is tudod, miről szól a topic.
Tehát mindenképpen függvényt írnál és saját magad dolgoznád fel a szöveget?
- A hozzászóláshoz be kell jelentkezni
Halk megjegyzés: Elég sok, mondhatni napi kapcsolatban volt a kolléga a telefonszámok világával, meg a feldolgozásukkal, úgyhogy nagyobb sejtése lehet arról, miről szól a topic, mint te gondolod.
- A hozzászóláshoz be kell jelentkezni
Nem a tudását akartam megkérdőjelezni, max a stílust, miközben a végén elismerte, hogy tudja miről van szó. Mindezt mosoly jellel ahogyan ő is tette. Röviden, sértődést sem szerettem volna.
- A hozzászóláshoz be kell jelentkezni
Oké, nekem könnyebb, szűk három év alatt volt időm megszokni :)
- A hozzászóláshoz be kell jelentkezni
Akkor majd egyszer bemutatsz neki. Bár feltételezem, hogy nem emlékszel rám. Már vagy öt éve találkoztunk utoljára, ha nem több. :-|
- A hozzászóláshoz be kell jelentkezni
Bucko kollégát szerintem még régebben láttam :-P
- A hozzászóláshoz be kell jelentkezni
Azt azért tudod, ki vagyok? :)
- A hozzászóláshoz be kell jelentkezni
Fotó alapján rémlik valami... ;)
- A hozzászóláshoz be kell jelentkezni
Törölhető.
- A hozzászóláshoz be kell jelentkezni
Legyen függvény, de inkább C szűrő. Bár awk-ban is készítettem egy kisöccsét.
Ez a kifejezés +361\d{7} helyesen leírva... A továbbiakban nem írom a +36-ot, és a számokat tartalmazó mezőt"=T van a kezünkben. ...Így is meghatározható:
12000000 <= atoi(T) <= 19999999
A vizsgált körzetszámokra készíthető egy lista. (Alias adatbázis.)
No, ez már megfelel a Nemzeti Számozási Tervnek, de nem biztos, hogy érvényes a hívószám.
Ehhez a "kijelölt" állapotú számmezők listájáig kell finomítani az adatbázisunkat.
A teljesség kedvéért ehhez még hozzá kell tenni a hordozott számok listáját, és akkor kiderül minden megfelelő formátumú, egyúttal létező hívószám.
A fenti ábrázolás lényege az a felismerés, hogy 32 bites int-be belefér bármelyik telefonszám, ezért gazdaságosan tárolható. Az előforduló kb. 15M telefonszám mindössze 60MB-ba sűríthető.
Az előnye :), hogy ilyet nem lehet sql-ben tárolni, de pl. BerkelyDb vagy asszociatív tömb (awk) kiválóan megfelel.
Természetesen nem szükséges ilyen szószátyár módon diszket pazarolni! Elegendő a létező számmezőkre egy index (4 byte), amelyhez tartozik 1000x1 bit, azaz 129 byte/számmező. Ez a tárolási mód < 10MB adatmennyiséget jelent, így gyorsan lekérdezhető.
- A hozzászóláshoz be kell jelentkezni
Itt sajnos kötve vagyok PHP5.x-hez, webes oldalnál egy hosting cégnél, ahol nincs CLI hozzáférésem. Egyéb okokból a MySQL-hez is kötve vagyok és hogy abban kell tárolnom az egyes telefonszámokat pár járulékos adattal, amik előfordultak.
- A hozzászóláshoz be kell jelentkezni
Ez van - anno takarékosan kellett bánni az erőforrásokkal, most meg ez sajnos egyre kevésbé szempont :)
- A hozzászóláshoz be kell jelentkezni
Feladat függő. Kellett nekem többgépes prímszámkeresőt írnom, sok GB RAM társaságában gépenként (párhuzamos programozás). Fordított nyelvről lévén szó, ott tudtam élni a bitekre való leképzéssel meg persze pár egyéb trükkel. Egész jó lett és (számomra) meglepően gyors.
Telefonszámok terén meg kb összesen háromezerről van (eddig) szó, kb 50 db-al ha bővül és kb 70-80 lekérés lehet hétköznaponként. Másrészt nem nekem kell eldönteni hogy valós-e a szám (létezik-e ténylegesen adott körzetszám), mert azt előzőleg ellenőrizték már. Nekem csak annyi kell, megfelel-e egy általános mintának a szám (nem írták-e el felvitelkor). Mobilnál és bp-i számnál legyen 7 további számjegy az előfizető azonosítására, míg egyéb körzetszámoknál hat darab számjegy. Szó sincs tárolási optimalizációról vagy egyebekről. Ezért döntöttem szimpla regex ellenőrzés mellett.
- A hozzászóláshoz be kell jelentkezni
Azért be lehet rakni MySQL-be is a limiteket. Seek >= és a találat mellé kell egy flag, ami jelzi a számmező érvényességét. Azért érdemes megcsinálni, mert az adat az adat marad, és nem kerül a kódba.
Gondolj bele, ha megváltozik a számozási rendszer! Betöltöd az új limiteket, aztán már csak a felmarkolt zsozsót kell elszállítani a kocsmába. :)
- A hozzászóláshoz be kell jelentkezni
Lazán kapcsolódik: https://github.com/gherkins/regexpbuilderphp
- A hozzászóláshoz be kell jelentkezni