regexp a végén ne legyen...

Sziasztok,

Remélem nem volt még ezerszer téma, énnem találtam :)
Előre is elnézést, nem fogom tudni jól megfoglamazni ezt már most tudom :)

Szóval azt szeretném megoldani, hogy egy regexp kifejezés úgy adjon eredményt, hogy az első néhány karaktert tartalmazza, az utolsót viszont nem.
Tehát pl.:
(7400([0-9a-b]{2})(.*?)(?!7400))

ezzel azt akartam mondani, hogy amit keresek, az úgy kezdődik, hogy 7400 majd van két karakter, ami vagy szám, vagy betű, majd tetszőleges karakterek, ami nem tartalmazhat 7400-át, azaz, ha 7400-át talál, azt már ne vegye bele az eredménybe. Egyértelműen azért, mert onnan már a következő találat kezdődik...

A string kb ilyen:

7400([0-9a-b]{2})(.*?)7400([0-9a-b]{2})(.*?)7400([0-9a-b]{2})(.*?)7400([0-9a-b]{2})(.*?)7400

Ha simán ez a kifejezésem:

(7400([0-9a-b]{2})(.*?)7400)

Azzal az a baj, hogy minden másodikat találja meg, pont azért, mert átfedés van a keresett karakterláncok között.

Szóval, hogyan tudom megoldani, hogy a következő 7400 már a következő találat eleje legyen, ami erre match-el:
(7400([0-9a-b]{2})(.*?)

Bocsi mégegyszer az értelmetlen fogalmazásért, és köszi előre is a válaszokat!

Hozzászólások

Szabályos kifejezésekben tagadást megfogalmazni meglehetősen nehéz, mivel a szabályrendszer alapvetően illeszkedésre és nem "nemilleszkedésre" van kihegyezve.

Ennek megfelelően én minden nem soreleji 7400 elé beillesztenék egy újsor karaktert, majd az így kapott többsoros állapotot soronként dolgoznám fel, kizárva ezzel a találatok közti "áthallást". A végén ha kell, visszaállíthatod az eredeti állapotot az újsorok törlésével.

---
Science for fun...

Szia,

Az újsor jel beillesztésén én is gondolkodtam, kicsit másképp: 7400 mentén split, de ehhez át kéne írni a már jól működő kódot is, ezért lett ez elvetve.
Tudom, hogy sajnos a nemilleszkedés nem profilja a regexp-nek, de vannak a (számomra) mágikus lookaround-dok, amikhez már nem értek. Azokkal valahogy meg lehet oldani, hiszen nem csak én használnám őket erre :)
Legalábbis úgy tudom, hogy ez lenne az irány, de azért is nem említettem, mert ilyen szinten már nem értek a regexp-hez :(

Szerintem is sokkal jobban olvashato lenne a kod, ha splittel oldanad meg, de ha jol ertem, hogy mit akarsz, akkor olvasd el itt a "Matching a pattern that doesn't include another pattern" szekciot. Egy pelda perlben (azaz a regex PCRE):


$ perl -le '$s="7400asd7400qwe7400yxc"; print join("\n", $s =~ m/(7400(?:(?!7400).)*)/g)'
7400asd
7400qwe
7400yxc

ha két 7400 közötti karaktersorozatot keresel, akkor

s/\(7400\)\(.*\)\(7400\)/\2/g

persze így az utolsó 7400 utánit nem fogod megkapni...hmmm...még átgondolom :)

de awk-ban van erre valami gyönyörú NF RF BG XX ZZ YY :)

Attól függ, hogy milyen nyelven írod. Pythonban van (?!...) konstrukció, ami akkor illeszt, ha a zárójelben levő nem illeszkedik, de nem eszi meg a zárójelben levő stringet.
A te esetedben:
(7400([0-9a-b]{2})(.*?)(?!7400)