A PowerShell 2.0 két új operátort hoz be a repertoárjába, mindkettő tulajdonképpen korábban is használatos funkciókat hajt végre talán egy picit egyszerűbben. Az egyik a sztringek összefűzését végrehajtó –join operátor:
PS C:\> "egy", "kettő", "három" -join "-"
egy-kettő-három
Az operátor bal oldalán áll az összefűzendő szövegek tömbje, jobb oldalán meg az összefűzéskor beillesztett karakter vagy sztring.
Érdekes módon, egyoperandusú operátorként is használhatjuk, de ehhez szerintem egy picit PowerShell-idegen formátumot kell alkalmazni:
PS C:\> -join ("egy", "kettő", "három")
egykettőhárom
Ilyenkor az összefűző karakter egy üres-sztring. Én személy szerint nem igazán javaslom a használatát.
Megjegyzés
Ráadásul itt azért kell a zárójelet használni, mert a PowerShell parancsfeldolgozója az egytagú operátorokat nagyobb precedenciájúnak tekinti, mint a többparaméteres operátorokat (jelen esetben a vessző tömboperátort), így a zárójel nélkül nem igazán jó eredményt kapunk:
[66] PS C:\> -join "egy", "kettő", "három"
egy
kettő
három
Hiszen itt valójában a (-join "egy"), "kettő", "három" kerül végrehajtásra.
A művelet fordítottját, azaz a szétdarabolást a –split operátor végzi:
PS C:\> "egy-kettő-három" -split "-"
egy
kettő
három
Ráadásul ez regex szemlélettel működik alaphelyzetben, azaz számjegyek mentén való darabolást az alábbi kifejezéssel lehet végrehajtani:
PS C:\> "egy1kettő2három3" -split "\d"
egy
kettő
három
Ha még ez sem lenne elég, akkor $true vagy $false értékre kiértékelődő bármilyen PowerShell kifejezés is írható:
PS C:\> "egy-kettő+három.négy!öt" -split {$_ -eq "-" -or $_ -eq "+"}
egy
kettő
három.négy!öt
Ezt úgy kell értelmezni, mint egy csőfeldolgozást: érkeznek a karakterek a sztringből, és amelyik kielégíti a feltételt, amentén tördel.
A tördelés eredményét be is lehet korlátozni. Ha én csak maximum 3 darabot szeretnék kapni a széttördelés után, akkor a –split-nek még egy szám paramétert adva ezt megtehetem:
PS C:\> '1.2.3.4.5.6.7.8' -split "\.", 3
1
2
3.4.5.6.7.8
(Ugye itt sem felejtkezünk meg a regex szintaxisról, azaz a „.” mentén való tördeléshez a „\.” kifejezést kell használni.)
A tördelés operátorának van néhány beállítható opciója is. Ha az a kifejezés, ami mentén tördelni akarunk egyszerű kifejezés, és esetleg olyan karakterek is vannak benne, amelyek a regexben vezérlő karakterek, akkor használhatjuk a „SimpleMatch” opciót:
[1] PS C:\munka> 'Egy$kettő$három' -split '$',0
Egy$kettő$három
[2] PS C:\munka> 'Egy$kettő$három' -split '$',0, "simplematch"
Egy
kettő
három
A fenti első nem működött, hiszen a „$” jel speciális jelentésű a regexben, a második eset már a kívánt eredményt adta. Ha ilyen opciókat használunk, akkor kötelező használni a maximális darabszámot meghatározó paramétert is (0 jelenti az összes darabot), hiszen csak így kerül helyére a „simplematch” opció.
A regex típusú tördelésnél a regex összes opcióját használhatjuk:
[RegexMatch] [,IgnoreCase] [,CultureInvariant] [,IgnorePatternWhitespace] [,ExplicitCapture] [,Singleline | ,Multiline]
Ráadásul a –split operátornak van egy –csplit kis-nagybetű érzékeny változata is:
[67] PS C:\> "axb" -csplit "x"
a
b
[68] PS C:\> "aXb" -csplit "x"
aXb
Látható, hogy a fenti példákban a –csplit csak a kisbetűs „x” mentén tördelt.
A darabolásnál láttuk, hogy az a karakter(sorozat), ami mentén darabolunk, az nem fog szerepelni az eredmény darabjai között. Például a következő kötőjelek mentén történő darabolás eredményében nincs egy darab kötőjel sem:
[1] PS C:\> "egy-kettő-három" -split "-"
egy
kettő
három
Mi van akkor, ha erre mégis szükség van? Na de pontosan hogyan is szeretnénk megőrizni ezeket a kötőjeleket? Ha külön darabként, akkor nagyon egyszerűen zárójelbe kell tenni ezt a kötőjelet:
[2] PS C:\> "egy-kettő-három" -split "(-)"
egy
-
kettő
-
három
Ha az a cél, hogy az előtte levő darabhoz csatlakozzon a kötőjel, akkor valójában nem maga a kötőjel a törési pont, hanem a kötőjel és az utána következő betű közti pozíció. Ilyenkor tehát ezt a pozíciót kell meghatározni, nem pedig magát a kötőjelet. Ezt előretekintéssel és hátratekintéssel tudjuk megtenni:
[3] PS C:\> "egy-kettő-három" -split "(?<=-)(?=\w)"
egy-
kettő-
három
Ezt a gondolatot folytassuk, vajon hogyan lehet például egy szöveget két karakterenként feldarabolni? Jönne az ötlet, hogy zárójelezzük a két karaktert jelölő tagot:
[4] PS C:\> "abcdef" -split "(\w{2})"
ab
cd
ef
Ez láthatóan nem tökéletes, hiszen ilyenkor az első két karakternél már darabolhatunk, kijön a darab előtti rész, a semmi, majd a zárójelezés miatt a két karakter. Majd folytatódik a folyamat, így az eredményben lesz egy csomó üres szöveg. Persze ki lehetne ezt szűrni, de próbáljuk meg elegánsabban ezt megoldani! Használjuk az előretekintés-hátratekintés kombinációt ismét:
[5] PS C:\> "abcdef" -split "(?<=\w{2})(?=\w)"
ab
c
d
e
f
Nem lett tökéletes. Próbáljunk meg együtt gondolkodni a regexszel! Az ’ab’ után egyértelmű, hogy lehet tördelni, viszont a ’c’ után is lehet, hiszen a ’c’ utáni pozícióban is igaz, hogy volt előtte két karakter. Valahogy rá kellene venni a regexszet, hogy ha egy darabot letört, akkor azt már ne is vegye figyelembe, azaz kezdjen új életet. Szerencsére erre is van lehetőség egy eddig még nem tárgyalt jelölővel, ez a ’\G’. Itt megint csak fontos a nagybetűs G.
[7] PS C:\> "abcdef" -split "(?<=\G\w{2})(?=\w)"
ab
cd
ef
Ez már tökéletes eredményt adott.