PHP strstr alla 4-siffriga nummer

Permalänk
Medlem

PHP strstr alla 4-siffriga nummer

Hejsan
Jag håller på att testa lite saker inom PHP på min sida och har fastnat på en grej. Funktionen går ut på att lista alla filer jag har i en mapp vilket jag lyckats med men jag vill rensa bort delar av namnet på filerna. Koden jag behöver hjälp med ser ut såhär:

$files1 = scandir($dir); for($i=0;$i<count($files1);$i++) { $a = strstr($files1[$i], '####', true); echo $a. '<br/>'; }

Det jag scannar ser ut typ såhär: "namn årtal info" och jag vill bara ha "namn" på det jag scannar. Koden fungerar nästan som jag vill, ersätter jag "####" med t.ex. 2012 blir resultatet på sidan att den visar allt med 2012 som årtal och den visar endast "namn", nästan precis som jag vill. Jag vill ju se allting, oberoende på årtal. Det jag vill är att "####" ska betyda vilka 4 siffror som helst bara det är 4 siffror. Så frågan är: vad skall jag ersätta "####" med för att den skall leta efter allt som har 4 siffror i rad i namnet?
Jag ber om ursäkt om jag är otydlig, säg gärna till om något är oklart. Jag har googlat och testat några saker men inte fått något att fungera.

Visa signatur

Tack till SAiKoU för avataren!
Stationär: i5-8400 | MSI Z370-A PRO | 24 GB DDR4 | 850EVO 500GB | Corsair VX450 | 1060 6GB Windforce

Permalänk
Medlem

Vet inte om jag förstod dig riktigt rätt, är lite trött...
Men hoppas att det hjälper i alla fall

$files1 = scandir($dir); for($i=0;$i<count($files1);$i++) { // Om filnamnet innehåller fyra siffror $match = preg_match_all('/(.*\d{4}.*)/', $files1[$i]); if($match > 0) { // dela upp filnamet i en array efter mellanslag $filename = explode(' ', $files1[$i]); // Plocka ut namnet (som ligger först) $a = $filename[0]; // Skriv ut echo $a. '<br/>'; } }

Visa signatur

Mina poster är en illusion. Det som står skrivet här över står i själva verket inte där så inget av det som du läser är sant. Inte ens den här texten. Jag har själv ingen kunskap om det jag skriver och ingen bör således läsa eller ta in den information som står skrivet.

Permalänk
Medlem
Skrivet av rumpnisse:

Vet inte om jag förstod dig riktigt rätt, är lite trött...
Men hoppas att det hjälper i alla fall

$files1 = scandir($dir); for($i=0;$i<count($files1);$i++) { // Om filnamnet innehåller fyra siffror $match = preg_match_all('/(.*\d{4}.*)/', $files1[$i]); if($match > 0) { // dela upp filnamet i en array efter mellanslag $filename = explode(' ', $files1[$i]); // Plocka ut namnet (som ligger först) $a = $filename[0]; // Skriv ut echo $a. '<br/>'; } }

Koden gör inte riktigt det jag vill då namnet kan vara flera ord och den plockar bara ut det första ordet med din kod. Om filnamnet ser ut som "TPB AFK 2013 1080p h264-SimonKlose" får jag endast fram "TPB" och jag vill ha "TBP AFK", d.v.s. jag vill att den skall skriva ut allting i namnet före årtal. Hoppas du förstår mig nu. Tack så mycket för att du vill hjälpa till.

Visa signatur

Tack till SAiKoU för avataren!
Stationär: i5-8400 | MSI Z370-A PRO | 24 GB DDR4 | 850EVO 500GB | Corsair VX450 | 1060 6GB Windforce

Permalänk
Medlem
Skrivet av Fixoon:

Koden gör inte riktigt det jag vill då namnet kan vara flera ord och den plockar bara ut det första ordet med din kod. Om filnamnet ser ut som "TPB AFK 2013 1080p h264-SimonKlose" får jag endast fram "TPB" och jag vill ha "TBP AFK", d.v.s. jag vill att den skall skriva ut allting i namnet före årtal. Hoppas du förstår mig nu. Tack så mycket för att du vill hjälpa till.

I see. Testa detta:
Du borde för övrigt kunna använda foreach istället för for för att loopa igenom resultatet från scandir.
Här är en länk till en mer ingående förklaring på det reguljära uttrycket: http://regex101.com/r/hI4iV1

$files1 = scandir($dir); foreach($files1 as $file) { // matcha allt före fyra siffror som inte omsluts av något annat än mellanrum (dvs. 2003 matchar men inte 1080p (på grund av P:et)) // Finns ingen anledning att använda preg_match_all då det bara är en rad som ska kollas på preg_match('/(.+)\s(?<!\S)\d{4}(?!\S)/', $file, $matches); // Plocka ut namnet som är den första (och enda) matchningen $a = $matches[0]; // Skriv ut echo $a. '<br/>'; }

Edit: snyggade till det reguljära uttrycket lite:
Från: (.+)(?<![^\s])\d{4}(?![^\s])
till: (.+)\s(?<!\S)\d{4}(?!\S)
Why?
1. Onödigt att köra [^\s] när \S gör samma sak
2. la till \s efter titel matchen så att det inte följer med ett mellanrum i matchen.

Visa signatur

Mina poster är en illusion. Det som står skrivet här över står i själva verket inte där så inget av det som du läser är sant. Inte ens den här texten. Jag har själv ingen kunskap om det jag skriver och ingen bör således läsa eller ta in den information som står skrivet.

Permalänk
Medlem
Skrivet av rumpnisse:

I see. Testa detta:
Du borde för övrigt kunna använda foreach istället för for för att loopa igenom resultatet från scandir.
Här är en länk till en mer ingående förklaring på det reguljära uttrycket: http://regex101.com/r/hI4iV1

$files1 = scandir($dir); foreach($files1 as $file) { // matcha allt före fyra siffror som inte omsluts av något annat än mellanrum (dvs. 2003 matchar men inte 1080p (på grund av P:et)) // Finns ingen anledning att använda preg_match_all då det bara är en rad som ska kollas på preg_match('/(.+)\s(?<!\S)\d{4}(?!\S)/', $file, $matches); // Plocka ut namnet som är den första (och enda) matchningen $a = $matches[0]; // Skriv ut echo $a. '<br/>'; }

Edit: snyggade till det reguljära uttrycket lite:
Från: (.+)(?<![^\s])\d{4}(?![^\s])
till: (.+)\s(?<!\S)\d{4}(?!\S)
Why?
1. Onödigt att köra [^\s] när \S gör samma sak
2. la till \s efter titel matchen så att det inte följer med ett mellanrum i matchen.

Nästan precis som jag vill ha det, bara det att jag inte vill att årtalet skall skrivas ut. "TPB AFK 2013 1080p h264-SimonKlose" blir "TPB AFK 2003" och jag vill ha endast "TPB AFK". Kan man även skriva något som gör att den hoppar över att försöka skriva ut filer som inte har ett årtal i filnamnet? Jag har några filer som inte har det och det resulterar i error(Notice: Undefined offset: 0 on line 73($a = $matches[0];)) på sidan, alltså heter en fil t.ex. "TPB AFK 720p" vill jag att den ska hoppa över att försöka skriva ut den.
Tack så mycket!

Visa signatur

Tack till SAiKoU för avataren!
Stationär: i5-8400 | MSI Z370-A PRO | 24 GB DDR4 | 850EVO 500GB | Corsair VX450 | 1060 6GB Windforce

Permalänk
Inaktiv

Protip: http://regex101.com

Gör din egen regex så får du den precis som du vill Använd också grupper för att få fram saker som årtal, relgrupp osv i sina egna variablar.. Vet dock inte hur grupper stödjs i php regexps då det var längesen jag pillade med php nu.

Permalänk
Medlem
Skrivet av Fixoon:

Nästan precis som jag vill ha det, bara det att jag inte vill att årtalet skall skrivas ut. "TPB AFK 2013 1080p h264-SimonKlose" blir "TPB AFK 2003" och jag vill ha endast "TPB AFK". Kan man även skriva något som gör att den hoppar över att försöka skriva ut filer som inte har ett årtal i filnamnet? Jag har några filer som inte har det och det resulterar i error(Notice: Undefined offset: 0 on line 73($a = $matches[0];)) på sidan, alltså heter en fil t.ex. "TPB AFK 720p" vill jag att den ska hoppa över att försöka skriva ut den.
Tack så mycket!

Oops. Så går det om man inte testar.
$matches[0] innehåller hela resultatet medans $matches[1] innehåller första gruppen
Och så slänger vi in den if-satsen igen

$files1 = scandir($dir); foreach($files1 as $file) { // matcha allt före fyra siffror som inte omsluts av något annat än mellanrum (dvs. 2003 matchar men inte 1080p (på grund av P:et)) // Finns ingen anledning att använda preg_match_all då det bara är en rad som ska kollas på $match = preg_match('/(.+)\s(?<!\S)\d{4}(?!\S)/', $file, $matches); if($match > 0) { // Plocka ut namnet som är den första (och enda) matchningen $a = $matches[1]; // Skriv ut echo $a. '<br/>'; } }

Visa signatur

Mina poster är en illusion. Det som står skrivet här över står i själva verket inte där så inget av det som du läser är sant. Inte ens den här texten. Jag har själv ingen kunskap om det jag skriver och ingen bör således läsa eller ta in den information som står skrivet.

Permalänk
Medlem
Skrivet av rumpnisse:

Oops. Så går det om man inte testar.
$matches[0] innehåller hela resultatet medans $matches[1] innehåller första gruppen
Och så slänger vi in den if-satsen igen

$files1 = scandir($dir); foreach($files1 as $file) { // matcha allt före fyra siffror som inte omsluts av något annat än mellanrum (dvs. 2003 matchar men inte 1080p (på grund av P:et)) // Finns ingen anledning att använda preg_match_all då det bara är en rad som ska kollas på $match = preg_match('/(.+)\s(?<!\S)\d{4}(?!\S)/', $file, $matches); if($match > 0) { // Plocka ut namnet som är den första (och enda) matchningen $a = $matches[1]; // Skriv ut echo $a. '<br/>'; } }

Härligt, nu fungerar det precis som jag vill! Tack för att du tog din tid och hjälpte mig!

Visa signatur

Tack till SAiKoU för avataren!
Stationär: i5-8400 | MSI Z370-A PRO | 24 GB DDR4 | 850EVO 500GB | Corsair VX450 | 1060 6GB Windforce

Permalänk
Medlem
Skrivet av Fixoon:

Härligt, nu fungerar det precis som jag vill! Tack för att du tog din tid och hjälpte mig!

No problem.

Missa inte att kolla in det vi använt
foreach
preg_match
Wikipedia om reguljära uttryck
Hjälpmedel för att skapa reguljära uttryck (Som Haikarainen länkade till)

Visa signatur

Mina poster är en illusion. Det som står skrivet här över står i själva verket inte där så inget av det som du läser är sant. Inte ens den här texten. Jag har själv ingen kunskap om det jag skriver och ingen bör således läsa eller ta in den information som står skrivet.