Gå til innhold

Kan noen hjelpe meg å filtrere ut tekst fra en streng i LUA?


Anbefalte innlegg

Jeg har rotet meg helt bort her, med string.sub, string.find og så videre. Jeg sender et oppkall til en nettside, og det som kommer tilbake, ser sånn ut:

<Response Status="OK"><Item Name="ZoneID">10001</Item><Item Name="ZoneName">Stua</Item><Item Name="State">0</Item><Item Name="FileKey">2010725</Item><Item Name="NextFileKey">-1</Item><Item Name="PositionMS">0</Item><Item Name="DurationMS">252000</Item><Item Name="ElapsedTimeDisplay">0:00</Item><Item Name="RemainingTimeDisplay">Live</Item><Item Name="TotalTimeDisplay">Live</Item><Item Name="PositionDisplay">0:00 / Live</Item><Item Name="PlayingNowPosition">10</Item><Item Name="PlayingNowTracks">11</Item><Item Name="PlayingNowPositionDisplay">11 of 11</Item><Item Name="PlayingNowChangeCounter">2</Item><Item Name="Bitrate">0</Item><Item Name="Bitdepth">0</Item><Item Name="SampleRate">0</Item><Item Name="Channels">0</Item><Item Name="Chapter">0</Item><Item Name="Volume">0.91</Item><Item Name="VolumeDisplay">91%  (-4,5 dB)</Item><Item Name="ImageURL">MCWS/v1/File/GetImage?File=2010725</Item><Item Name="Artist">Brainstorm</Item><Item Name="Album">Scary Creatures</Item><Item Name="Name">Lift Your Eyes to See (Bonus Track)</Item><Item Name="Status">Stopped</Item></Response>

Innholdet i de forskjellige punktene varierer etter hva som spilles. Jeg kan hente ut noe som bare er ett ord sånn:

local _, _, Avspillingsartist = string.find('DEN LANGE TEKSTSTRENGEN', 'Artist">(%a+)<')

Da får jeg i dette tilfellet Masterplan som Avspillingsartist. Men jeg kan jo ikke bare spille musikk av artister med ett enkelt navn, hvordan skal jeg da få inn Iron Maiden? :rofl: Så er det noen LUA-kyndige der som kan fortelle meg hvordan jeg kan filtrere ut den teksten som ligger mellom feltnavnene, for eksempel det som ligger mellom "Album"> og <

Lenke til kommentar
Videoannonse
Annonse

Har ikke noe erfaring med LUA, men med litt hjelp fra google kom jeg fram til dette som ser ut til å fungere.
Det legger alle feltene inni en map type "map[felt]=verdi"

IDEONE
 

-- init variables
local text = '<Response Status="OK"><Item Name="ZoneID">10001</Item><Item Name="ZoneName">Stua</Item><Item Name="State">0</Item><Item Name="FileKey">2010725</Item><Item Name="NextFileKey">-1</Item><Item Name="PositionMS">0</Item><Item Name="DurationMS">252000</Item><Item Name="ElapsedTimeDisplay">0:00</Item><Item Name="RemainingTimeDisplay">Live</Item><Item Name="TotalTimeDisplay">Live</Item><Item Name="PositionDisplay">0:00 / Live</Item><Item Name="PlayingNowPosition">10</Item><Item Name="PlayingNowTracks">11</Item><Item Name="PlayingNowPositionDisplay">11 of 11</Item><Item Name="PlayingNowChangeCounter">2</Item><Item Name="Bitrate">0</Item><Item Name="Bitdepth">0</Item><Item Name="SampleRate">0</Item><Item Name="Channels">0</Item><Item Name="Chapter">0</Item><Item Name="Volume">0.91</Item><Item Name="VolumeDisplay">91%  (-4,5 dB)</Item><Item Name="ImageURL">MCWS/v1/File/GetImage?File=2010725</Item><Item Name="Artist">Brainstorm</Item><Item Name="Album">Scary Creatures</Item><Item Name="Name">Lift Your Eyes to See (Bonus Track)</Item><Item Name="Status">Stopped</Item></Response>'
local pattern = '<Item Name="(.-)">(.-)<'
local map = {}

-- for each match, add to map
for key,value in string.gmatch(text, pattern) do map[key] = value end

-- print each key,value pair in map
for key,value in pairs(map) do print(key,value) end
Endret av stelar7
Lenke til kommentar

Stelar7, takk for hjelpen! Hvis du ikke kan LUA, kan du tydeligvis masse om generell programmering! :) Med en liten endring funket det (det skal være gfind, ikke gmatch). Og med noen minutters tilpasning kom jeg fram til akkurat det jeg trengte. Variabelen Sone vil komme fra en annen funksjon, men jeg har lagt den inn her for å teste. Jeg testet alle sonene. Det eneste problemet er at resultatet av print-statementen ikke kommer i UTF, så norske tegn blir hakket i stykker. Jeg får se hvordan det ser ut når jeg sender det videre til nettsiden, som er UTF.

Sone = 9
local text = socket.http.request('http://localhost/MCWS/v1/Playback/Info?Zone=' .. Sone .. '&ZoneType=Index')
local pattern = '<Item Name="(.-)">(.-)<'
local map = {}
     
for key,value in string.gfind(text, pattern) do map[key] = value end
     
print(map.Artist)
print(map.Album)
print(map.Name)
map = nil

Sokkalf, dette programmet behandler det som strenger, ikke XML. Så det ser ut til å funke helt perfekt. :)

Lenke til kommentar

Det skjer ikke. Teksten er 100 % lik hver eneste gang. 100 %. Den kommer ikke fra en nettside, eller noe sånt, den kommer fra et medieavspillingsprogram og har vært kliss lik i omtrent ti år. Skulle de endre noe, fikser jeg det når det skjer. Men de er veldig forsiktige med å endre noe som helst fordi så mange kjører automatisering som er avhengig av syntaksen.

Endret av Mastiff
Lenke til kommentar

Skulle de endre noe, fikser jeg det når det skjer. Men de er veldig forsiktige med å endre noe som helst fordi så mange kjører automatisering som er avhengig av syntaksen.

 

 

Hadde du ikke hatt som målsetning å for enhverpris unngå å parse xml med en xml-parser kunne du ha fikset problemet _før_ det skjer. 

Syntaxen er XML, og vil være å betrakte som uforandret som sådan, selv om det faktisk er skjedd "ting" som gjør at parsingen din brekker. Det kan være nok at xml-biblioteket som brukes i medieavspilleren oppgraderes. Men det kan jo så fort gå bra, som man sier ...

Lenke til kommentar

Jeg påstår ikke at du tar feil. :) Jeg kan ikke mye om LUA, eller noen programmering, derfor bruker jeg bare de enkleste løsningene, og jeg programmerer stort sett ved å sette sammen snippets som andre har laget til andre ting, eller som jeg har bedt om hjelp med, som i denne tråden. Men uansett så vil en sånn endring være fikset på minutter, og det er ikke en kritisk del av hjemmeautomasjonen. Men hvordan ville du i så fall løst det?

 

Edit: Som XML-parsing, altså.

Endret av Mastiff
Lenke til kommentar

Edit: Som XML-parsing, altså.

Kan raskt vise deg en med Python.

from bs4 import BeautifulSoup

xml = '''\
<Response Status="OK">
  <Item Name="ImageURL">MCWS/v1/File/GetImage?File=2010725</Item>
  <Item Name="Artist">Brainstorm</Item>
  <Item Name="Album">Scary Creatures</Item>
  <Item Name="Name">Lift Your Eyes to See (Bonus Track)</Item>
  <Item Name="Status">Stopped</Item>
</Response>'''

soup = BeautifulSoup(xml, 'lxml')
artist = soup.find('item', {'name': "Artist"})
album = soup.find('item', {'name': "Album"})
name = soup.find('item', {'name': "Name"})
print('{}\n{}\n{}'.format(artist.text,album.text,name.text))
Output:

Brainstorm
Scary Creatures
Lift Your Eyes to See (Bonus Track)
Har du i det hele tatt søkt på på parser for Lua?

Regner med at det finnes.  

 

Det beste svar på hele stack overflow.

Every time you attempt to parse [X]HTML with regular expressions, the unholy child weeps the blood of virgins, and Russian hackers pwn your webapp.

Parsing HTML with regex summons tainted souls into the realm of the living.

Lenke til kommentar

Jeg påstår ikke at du tar feil. :) Jeg kan ikke mye om LUA, eller noen programmering

 

 

Nettopp, derfor tipset :-) Tenker nok løsningen din kan virke prikkfritt i mange år uten annet enn små justeringer, men det er jo en slags gaffa-løsning når det kommer til parsing av xml. Og så er det vel kjekkt å lære noe nytt? Selv om mange syns xml er gammaldags og tungvint i forhold til f.eks. json er det jo ganske utbredt.

 

Hvis du lurer på hvordan tror jeg en god start ville vært å google 'xml lua'. Fant denne siden: http://lua-users.org/wiki/LuaXml og må innrømme at jeg ikke helt får inntrykket av at xml-parsing-støtte i lua er helt tipp-topp. Her er noen eksempler  https://github.com/Cluain/Lua-Simple-XML-Parser

Endret av quantum
Lenke til kommentar

Jeg antar at det er en grunn til at du bruker Lua?

 

Som snippsat viser, så finnes det elegante løsninger til Python (og en del andre språk). Men hvis det quantam viser til stemmer, så har ikke Lua det. Og da blir spørsmålet, er det verdt tiden å lære seg å bruke et knotete bibliotek hivs dette virker, og du ikke er en programmerer?

Lenke til kommentar

Jeg antar at det er en grunn til at du bruker Lua?

 

Som snippsat viser, så finnes det elegante løsninger til Python (og en del andre språk). Men hvis det quantam viser til stemmer, så har ikke Lua det. Og da blir spørsmålet, er det verdt tiden å lære seg å bruke et knotete bibliotek hivs dette virker, og du ikke er en programmerer?

 

 

Vet ikke om jeg fant det beste LUA kan tilby, men det så jo noe magert ut ja ...

Lenke til kommentar

Takk for forslagene! Jeg fikk ikke gjort noe med det denne helgen, så jeg må nok se om jeg får tid neste helg. Men ja, det er en meget god grunn til at jeg bruker LUA: Jeg har Girder som navet i automatiseringen min, og det bruker LUA. Jeg vet at Python kunne gjort dette lettere, men det er dessverre ikke aktuelt å bruke. Jeg har mange års automatiseringsarbeid nedlagt i Girder, og det jeg driver med nå, er bare "glasur på kaka", så det ville aldri vært aktuelt å bytte. :green:

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...