parsolnom kene ilyen parametereket:
param1=abc
param2 = abc
param3 = "ab'c"
param4='a"b"c'
param5="abc=def"
egyaltalan megoldhato ez egy regexp-el? (most karakterenkent dolgozom fel...)
lenyeg hogy lehet ' es " is az idezojel (de nem is kotelezo) es azon belul a masik fajta idezojel sima karakterkent mukodik.
es akkor meg a \' nem is neztuk, de az talan nem is kell.
pythont hasznalok, ami elvileg perl regex kompatibilis nagyjabol...
- 1058 megtekintés
Hozzászólások
Ha jól értem: [abc\'\"]{3,5}
param5-nél mi a terv? kiértékelni?
- A hozzászóláshoz be kell jelentkezni
nem jol erted...
kb ez kene legyen az output:
param1=abc
param2=abc
param3=ab'c
param4=a"b"c
param5=abc=def
tehat a folosleges whitespacet (= elott/utan) es az idezojeleket kene eltuntetni, param neve es az ertek kellene belole, barhogy is irtak.
- A hozzászóláshoz be kell jelentkezni
https://regex101.com/r/3aNIOD/1
és most?
pill
https://regex101.com/r/3aNIOD/2
Ezzel szétkaptam 3 tömbbe.
- A hozzászóláshoz be kell jelentkezni
az a baj hogy ez matchelni fog a hibasra is: param7="hello'
illetve benne marad az utolso match groupban az idezojel is, ami nem kene.
meg aztan (bar ezt nem irtam eddig) matchelni kene utana egy sorvege vagy ;-re is ami nem lehet az idezojelen belul :)
- A hozzászóláshoz be kell jelentkezni
Ez esetleg?
/^(\w+)\s?=\s?(['\"]?)(\S*)\2$/gm
https://regex101.com/r/hbsISt/1
így elvileg \1 és \3 tartalmazza a lényeget (bár lehet van ennél szebb forma, de most hirtelen ezt találtam)
- A hozzászóláshoz be kell jelentkezni
szuper, koszi! remlett hogy valahol lattam olyat hogy lehet matchelni masik matchre de nem igazan talaltam/ertettem hogyan...
kicsit kibovitettem igy elvileg az opcionalis tovabbi parametereket meg berakja \4-be:
^(\w+)\s?=\s?(['\"]?)(.*?)\2\s?(;.*)?$
pl: param1="a bc"; param8=efg; param9="aaa"
https://regex101.com/r/3UXWPt/1
szerk: kezdek belejonni, igy mar a \" sem problema:
^\s*(\w+)\s*=\s*(['\"]?)((?:\\.|.)*?)\2\s*(;.*)*$
param3 = " ab'\"; c" ; p23=55
ugyanakkor nem vagyok meggyozodve rola, hogy ez igy gyorsabb, mint karakterenkent vegigmenni rajta (for ciklus + state machine)...
- A hozzászóláshoz be kell jelentkezni
Írni könnyebb, mint olvasni. :)
Emiatt is szoktam feldarabolni és inkább jobban szétszedni, olvashatóvá.
- A hozzászóláshoz be kell jelentkezni
Az ember azt hinné hogy megoldást is írsz. Nem csak pénzügyi elemzést.
- A hozzászóláshoz be kell jelentkezni
?
- A hozzászóláshoz be kell jelentkezni
viccelni próbáltam bocsi :-)
- A hozzászóláshoz be kell jelentkezni
Az nem baj, csak nem értem.
Hülyeséget írtam?
- A hozzászóláshoz be kell jelentkezni
(?:(\b\w+\b)\s*=\s*(['\"]?)(.*?)(\2))(?=\s*;\s*|\s*$)
gyorsnak nem gyors, de erre az elbaszott szarra csoda lenne. de ha tudnál rajta reszelni, hogy valamennyire egységes legyen az input akkor gyorsabbá lehetne tenni
- A hozzászóláshoz be kell jelentkezni
Ez egy nagyon hasznos oldal összerakni regexp-et, bemásolsz egy példát és kijelölgeted
https://regex-generator.olafneumann.org/
Ezen pedig egész jól lehet próbálgani az eredményt
https://regexr.com/
- A hozzászóláshoz be kell jelentkezni
Ilyesmire gondolsz?
#!/usr/bin/env python3
import re
pattern = r"(?P<variable>[_a-zA-Z][_a-zA-Z0-9]*)\s*=\s*(?P<value>\"[^\"]*\"|'[^']*'|[^ '\"]*)"
test_list = '''param1=abc
param2 = abc
param3 = "ab'c"
param4='a"b"c'
param5="abc=def"'''.split("\n")
for test_case in test_list:
res=re.match(pattern, test_case)
print(f"{test_case=}: {res['variable']=} {res['value']=}")
test_case='param1=abc': res['variable']='param1' res['value']='abc'
test_case='param2 = abc': res['variable']='param2' res['value']='abc'
test_case='param3 = "ab\'c"': res['variable']='param3' res['value']='"ab\'c"'
test_case='param4=\'a"b"c\'': res['variable']='param4' res['value']='\'a"b"c\''
test_case='param5="abc=def"': res['variable']='param5' res['value']='"abc=def"'
Azt nem specifikaltad, mi a teendo, ha nincs macskakorom, csak elkezded irni a dolgot
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
majnem, csak nekem az idezojelek nelkul kene a value :)
- A hozzászóláshoz be kell jelentkezni
Jogos
#!/usr/bin/env python3
import re
pattern = r"(?P<variable>[_a-zA-Z][_a-zA-Z0-9]*)\s*=\s*(?:\"(?P<value1>[^\"]*)\"|'(?P<value2>[^']*)'|(?P<value3>[^ '\"]*))"
test_list = '''param1=abc
param2 = abc
param3 = "ab'c"
param4='a"b"c'
param5="abc=def"'''.split("\n")
for test_case in test_list:
res=re.match(pattern, test_case)
value=res['value1'] or res['value2'] or res['value3']
print(f"{test_case=}: {res['variable']=} {value=}")
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
Regex megoldást írtak fentebb, viszont én hasonló esetben inkább egy protobuf/json/yaml/akármi fájlt olvasnék be, és akkor ingyen van hozzá parser, ami a trükkösebb dolgokat is kezeli (escape karakterek meg ilyesmi) és a felhasználó is ismerni fogja a formátumot. Még a shell is lehet jó, pl. A=12 B="3 4" C=$(date) programom.py vagy programom.py --a=12 --b="3 4" --c=$(date).
- A hozzászóláshoz be kell jelentkezni
hat ha lenne rahatasom az input formatumara, akkor en is :)
- A hozzászóláshoz be kell jelentkezni
Ha sajat programhoz tartozo configfile, akkor +1 erre. Ezt viszont nem irta.
Ha letezo fileformatum, akkor nem annyira jo otlet, mert hoz magaval minden egyebet. Kiveve persze, ha pont a megfelelo formatum parseret talalod meg.
Ha valami egzotikus program configjat kell parse-olni amiben "a=5" jellegu sorok vannak, nem jo otlet rakuldeni pl. egy ini file parsert, csak mert az is megeszi ezeket a sorokat.
Olyan is lehet, hogy pont a configokat akarja kijavitani egy masik program szamara. (multkor jpeg kepek hibait kereste)
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
a valtozatossag kedveert meg mindig emaileket parsolok, azon belul is a Content-*: headereket... probaltam eloszor rakeresni de csak ilyen szepsegeket talaltam: https://stackoverflow.com/questions/20771794/mailrfc822address-regex
- A hozzászóláshoz be kell jelentkezni
Az lett volna a masik tippem :)
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
- A hozzászóláshoz be kell jelentkezni
Option 1: Go use the python-mimeparse third-party library.
hat amit 10 sorban vagy 1 regexpel meg lehet irni arra nem hasznalnek kulso fuggoseget
raadasul (beleneztem a forrasaba) ez is a cgi.parse_header(mime_type)-t hasznalja:
Option 2: use cgi.parse_header
As of Mar 2023, the current official way of doing this, now that cgi
is deprecated
using email.message.Message
epp ettol probalok szabadulni...
- A hozzászóláshoz be kell jelentkezni
(\w+)\s*=\s*(".*?"|'.*?'|\w+)
(\w+)
- Elkapja a paraméter nevét, ami betűkből és számokból állhat.\s*=\s*
- Megkeresi az egyenlőségjelet, amely előtt és után tetszőleges számú szóköz állhat.(".*?"|'.*?'|\w+)
- Elkapja a paraméter értékét, amely idézőjelek között állhat (akár egyszeres, akár dupla idézőjelek között), vagy csak simán szöveg lehet (számokkal és betűkkel).
- A hozzászóláshoz be kell jelentkezni
A ? miert kell? Greediness miatt?
Arpi feljebb azt irta, hogy a "" es a '' nem kell neki az eredmenybe, csak a belseje.
A strange game. The only winning move is not to play. How about a nice game of chess?
- A hozzászóláshoz be kell jelentkezni
(\w+)\s*=\s*(?:(?:"([^"]*)"|'([^']*)'|([^;\n"']+))\s*(?:;|$))
Most elolvastam a közbenső igényeket is, és itt tesztelhető: https://regex101.com/r/KmWmNf/3
A magyar leírás benne van a linkben is archiválás céljából.
- (\w+) - Elkapja a paraméter nevét.
- \s*=\s* - Keresi az egyenlőségjelet a felesleges szóközökkel együtt.
- (?:"([^"]*)"|'([^']*)'|([^;\n"']+)) - Elkapja az értéket a következő feltételekkel:
- "[^"]*": Dupla idézőjelek közötti szöveget, ami nem tartalmaz további dupla idézőjeleket.
- '[^']*': Egyszerű idézőjelek közötti szöveget, ami nem tartalmaz további egyszerű idézőjeleket.
- [^;\n"']+: Szöveget, ami nem tartalmaz sem pontosvesszőt, sem sorvégét, sem idézőjelet.
- \s*(?:;|$) - Keres egy opcionális sorvégi vagy pontosvessző elválasztót.
- A hozzászóláshoz be kell jelentkezni
Jobb oldalt van a kiértékelés. A megoldásoddal különböző group-ba kerül be a param_value. Ez nem gond?
Én abból indultam ki, hogy jobb lenne kapni m x n-es tömböt, ami nálam n=3 volt, n[0] => param_name, n[2] => param_value
- A hozzászóláshoz be kell jelentkezni
Igen de Árpi írta hogy python, ez pedig így rakható össze:
import re
regex_pattern = r'(\w+)\s*=\s*(?:"([^"]*)"|\'([^\']*)\'|([^;\n"\']+))\s*(?:;|$)'
test_text = """
param1=abc
param2 = abc
param3 = "ab'c"
param4='a"b"c'
param5="abc=def"
param6=abc; param7="hello'
param8='Itt; a vége'
"""
matches = re.finditer(regex_pattern, test_text, re.MULTILINE)
result = []
for match in matches:
# Paraméter neve és értéke
param_name = match.group(1)
param_value = match.group(2) or match.group(3) or match.group(4)
# Eredmény hozzáadása a listához
result.append(f"{param_name}={param_value}")
result
És a tömb:
['param1=abc', 'param2=abc', "param3=ab'c", 'param4=a"b"c', 'param5=abc=def', 'param6=abc', 'param8=Itt; a vége']
- A hozzászóláshoz be kell jelentkezni
Most már látom.
Én úgy értettem, hogy a param_value-ból pedig ki szeretné szedni az idézőjeleket.
- A hozzászóláshoz be kell jelentkezni
Ez az output igénye volt itt írta Neked: https://hup.hu/comment/2996526#comment-2996526
- A hozzászóláshoz be kell jelentkezni
na csinaltam benchmarkot:
for: az en regi for ciklusos state-machine-szeru megoldasom
re1: Atis89 verzioja alapjan, re2: FeriX verzioja alapjan
python3.10:
for: 0.9218964576721191
re1: 0.2517125606536865
re2: 0.17335128784179688
python3.11:
for: 0.5490951538085938
re1: 0.2325422763824463
re2: 0.16354846954345703
pypy3.10:
for: 0.08430266380310059
re1: 0.15888285636901855
re2: 0.07618188858032227
erdekes hogy pypy-vel a for ciklus beelozte az egyik regexpet is...
400k mintan futott, elotte addig reszeltem a regexpeket mig egyforma lett a kimenetuk...
http://thot.banki.hu/arpi/rerere/
koszi mindnekinek az otleteket!
- A hozzászóláshoz be kell jelentkezni
Egészségedre :-) Ebben a topikban az a vicces számomra hogy ugyan abból a megfontolásból pénteken nem használtam egy NodeJS csomagot, ami miatt Te se csak egy funkcióra, csak azért hogy kommenteket írhassak a JSON fájlba. Inkább írtam egy reguláris kifejezést és parzolás előtt lefuttattam hogy, eltávolítsam kommenteket:
/\/\/.*$|^\s*\/\/.*$/gm;
Ez a regex kifejezés minden olyan sort eltávolít a JSON szövegből, amely //
-al kezdődik, legyen az a sor elején vagy a végén.
- A hozzászóláshoz be kell jelentkezni
OT
Én csak azt nem értem, hogy miért van itt két alternatíva? Az első fele illeszkedik a sor végén álló megjegyzésekre - pl. egy utasítás mögött, de kihagyja a megjegyzés előtt a szóközöket. A második fele azokkal a sorokkal foglalkozik, ahol az egész sor csak megjegyzés - de a sor elején levő white space-ekre is illeszkedik. Miért nem jobb egyszerűsíteni egyetlen mintára, ami mindig illeszti a megjegyzés előtti szóközöket is?
/\s*\/\/.*$/gm;
/OT
- A hozzászóláshoz be kell jelentkezni
Leírom nehogy valakit félrevezessen: az onnantól (hogy van benne komment) már nem szabályos JSON file azt tudjuk ugye?
Most utánaolvasva van egy érdekes gyakorlat: emberünk belerakja "_comment" mezőbe a kommentárját, attól az json marad, sőt akár ki is olvashatja feldolgozáskor ha akarja.
Gábriel Ákos
- A hozzászóláshoz be kell jelentkezni
Nekem ez egy konfiguráció, leíró, minden is JSON, ami privát fejlesztésben található, de hívjuk majdnem JSONC-nek. Én is tudom, hogy hogyan kell elkülöníteni aláhúzással azt amit ideiglenesen el szeretnék távolítani, de az olvasása közben, a látványban nem feltűnő elkülönítés. Az én szememnek a komment a kényelmes.
- A hozzászóláshoz be kell jelentkezni
ott az eltérés hogy az első variáns az "bárhol kezdődő // -re" matchel és bármi lehet előtte, nem csak whitespace.
Ez szerintem veszélyes konstrukció amúgy mert semmi se zárja ki hogy a normál adatban legyen // akárhol egy string közepén.
Gábriel Ákos
- A hozzászóláshoz be kell jelentkezni
Terveztem hogy lesz benne url, hiszen a dupla per a világ legelterjedtebb ismétlődő karaktere :-) a két t betű után.
Meg ugye elég sok kérdést felmerül, például az escape / \//, stb, meg hogy aposztróf között is lehet, meg még ki tudja mi jön majd fejlesztés közben.
De az a szerencse hogy bővíthető:
- A hozzászóláshoz be kell jelentkezni
- A hozzászóláshoz be kell jelentkezni
Próbáld ki az enyémet is. Annak az az előnye a többiekével szemben hogy jól matcheli a key-value párokat :P
- A hozzászóláshoz be kell jelentkezni
nezegettem azt is, de a lenyegi resze (opcionalis idezojel matchelese) ugyanaz volt, vagy nem vettem eszre valamit?
vagy arra gondolsz hogy ez csak az elso parametert matcheli, nem a (param)=(value) ; (tobbi)-t es igy maskepp lehet ciklusozni (for in matches, es nem pedig while-al amig van tobbi)?
- A hozzászóláshoz be kell jelentkezni
kicsit moddoltam, igy mar jo eredmenyt ad mindenre (sajnos a param neveben lehet - es * is, meg szamok is):
https://regex101.com/r/l0Anq0/1
viszont eddig ez a leglassabb regex :( bar meg igy is 3x gyorsabb python3.10-el (2x 3.11-el) mint a karakterenkenti for
osszekombinaltam a masikkal is, pypy-vel az lett a leggyorsabb:
https://regex101.com/r/CyIdTD/1
python3.10:
for: 0.9325275421142578 A'rpi (for karakterenkent)
re1: 0.24773311614990234 Atis89
re1f: 0.30788111686706543 gazsiazasz
re2: 0.1703355312347412 FeriX
re2f: 0.20905804634094238 FeriX+gazsiazasz
python3.11:
for: 0.5474085807800293
re1: 0.23268747329711914
re1f: 0.2706611156463623
re2: 0.16312909126281738
re2f: 0.18561649322509766
pypy3.10:
for: 0.08565855026245117
re1: 0.1592862606048584
re1f: 0.17911410331726074
re2: 0.07767152786254883
re2f: 0.07328653335571289
- A hozzászóláshoz be kell jelentkezni
Mr. Elvesziamunkánkat szerint:
import re
# A regex minta a különböző formátumú paraméterértékek illesztéséhez
pattern = r'(?<=\=)\s*(".*?"|\'.*?\'|[^\s]+)'
# Példa sztringek a regex minta teszteléséhez
test_strings = [
"param1=abc",
"param2 = abc",
"param3 = \"ab'c\"",
"param4='a\"b\"c'",
"param5=\"abc=def\""
]
# A regex minta alkalmazása minden tesztsztringre, és az egyezések kinyerése
extracted_values = [re.search(pattern, s).group(0) for s in test_strings if re.search(pattern, s)]
- A hozzászóláshoz be kell jelentkezni