Hogyan parsolnátok akármiben a következőhöz hasonló változót:
USE="nls nptl nptlonly unicode emacs bash-completion X gtk jpeg jpeg2k gif tiff wmf
truetype png nsplugin alsa opengl gnome dvd dbus eds bzip2 dvdr qt3"
Amit nem lehet kihasználni:
* hogy hasonlít egy programsorhoz
* hogy az egyenlőségjel és a idézőjel valamint a változónév és az egyenlőség jel között nincs semmi
* hogy a változó nagybetűs
Amit ki lehet:
* A folytatódó indentálva van
* A változó nevek nincsenek indentálva
Perl, Python, Java érdekel.
Eselteg ha valaki tuja a nevét a problémának, linket bármit tud adni, érdekel.
- 1404 megtekintés
Hozzászólások
JavaCC-vel lehet például parsert generálni. Ez azonban lehet, hogy ágyúval verébre. Csak alap Javát használva kézzel leprogramozva egy működő alap verzió (hibákat nem ismeri fel, de hibátlan inputot kb jól kezel):
package trials;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Map;
import java.util.TreeMap;
public class Parse {
public static void main(String[] args)
{
String toParse="USE=\"alma korte\n\tszolo szilva\"\n" +
"MASIK=\"kutyus cicus\n\tkutya macska\"\n";
try
{
System.out.println(""+Parse.parse(toParse));
}catch(Exception e)
{
// something messed up
e.printStackTrace();
}
}
public static Map parse(String toParse) throws IOException
{
return new Parse(toParse).parse();
}
private Parse(String toParse)
{
this.toParse=toParse;
}
private String toParse;
private StringBuilder value=new StringBuilder();
private String currentKey=null;
private TreeMap ret=new TreeMap();
private Map parse() throws IOException
{
Reader r=new StringReader(toParse);
BufferedReader br=new BufferedReader(r);
String line;
while((line=br.readLine())!=null)
{
if(line.length()>0)
{
// TODO szűrjük a megjegyzéseket, meg ilyesmiket
char elsobetu=line.charAt(0);
if(Character.isWhitespace(elsobetu))
{
appendLine(line);
}
else
{
int idxEqu=line.indexOf("=");
if(idxEqu>=0)
{
String key=line.substring(0,idxEqu);
key=trim(key);
line=line.substring(idxEqu+1);
int idxKorom=line.indexOf("\"");
if(idxKorom>=0)
{
processVariable();
currentKey=key;
appendLine(line.substring(idxKorom+1));
}
}
}
}
}
processVariable();
return ret;
}
private void processVariable() {
if(currentKey!=null)
{
ret.put(currentKey, value.toString());
value=new StringBuilder();
}
}
private void appendLine(String line) {
int idxKorom=line.indexOf("\"");
if(idxKorom>=0)
{
line=line.substring(0,idxKorom);
}
value.append(line);
}
String trim(String s)
{
StringBuilder ret=new StringBuilder();
for(int i=0;i
{
char ch=s.charAt(i);
if(!Character.isWhitespace(ch))
{
ret.append(ch);
}
}
return ret.toString();
}
}
- A hozzászóláshoz be kell jelentkezni
Kösz, megnézem majd. Kiindulásnak jó.
Direkt azért mondtam, hogy a favágó módszer érdekel, mert ez egy viszonylag általános probléma. Persze, aki ismeri, könnyen kitalálhatja, hogy a Gentoo-m make.conf-jából vágtam ide egy sort, de azt próbáltam kihangsúlyozni, hogy nem a példa a lényeg.
Azért fura, hogy senki nem írt ilyen könyvtárat scriptnyelvekhez, vgy hogy az alap könyvtárak nem tudják.
- A hozzászóláshoz be kell jelentkezni
had boffentsek en is ide valamit:
$x = 'USE="nls nptl nptlonly unicode emacs bash-completion X gtk jpeg jpeg2k gif tiff wmf
truetype png nsplugin alsa opengl gnome dvd dbus eds bzip2 dvdr qt3"';
$x =~ /(\w+)\s*=\s*"([^"]*")/m;
print $1;
@y=split /\s+/m, $2;
use Data::Dumper;
print Dumper \@y;
zsolt
- A hozzászóláshoz be kell jelentkezni
Ezt a regexet minden rendszer elfogadja vajon? Perl-ről tudom, hogy elég széles a regex supportja, de mi a helyzet a többivel (Python, Java)?
És köszönöm neked is.
- A hozzászóláshoz be kell jelentkezni
nem tudom pontosan. pythonban lehet hasonloan megvalosithato, ugyanis a fenti regex nagyon egyszeru, csak a vegen az 'm' modosito perl specifikus.
javat kerulom, lsd a legelso hozzaszolas...
zsolt
- A hozzászóláshoz be kell jelentkezni
Gondolom az 'm' a lelke a dolognak (az felel a töbsorosságért), ergó ha az valóban perl specifikus, az gáz. Nem kicsit, nagyon.
- A hozzászóláshoz be kell jelentkezni
utanna kell nezni a kivant nyelvek manualjaban...
kikerulheto meg egy sor hozzaadasaval:
$2 =~ s/\n//;
zsolt
- A hozzászóláshoz be kell jelentkezni
Igen, erre én is gondoltam, csak a pár nyelv azt csinálja, hogy bepakolja a sort, hozzányomja a \n-t és csá, nem veszi figyelembe, hogy a regex több sorról akarna szólni. De mindent ki fogok próbálni.
- A hozzászóláshoz be kell jelentkezni
Javában a regexp nem kezeli specifikusan a sorvégét, ugyanúgy regexp-pel kell leírni, mint a többi karaktert. Tehát simán a \n karaktert (vagy a \r-t is, ha windows is kontárkodik) kell használni sorvége jelzésre.
- A hozzászóláshoz be kell jelentkezni
- perl: "m"
- python: "re.M", v. "re.MULTILINE"
- java: "Pattern.MULTILINE"
- A hozzászóláshoz be kell jelentkezni
Aham, köcönöm. Ez volt álmaim vágya.
- A hozzászóláshoz be kell jelentkezni
A PCRE (libPCRE) egy perl-kompatibilis regexpet ismero lib. Sok nyelven csinaltak hozza interface-t, en eddig php-bol (preg_match es tarsai), C/C++-bol hasznaltam, de valoszinuleg sok masbol is lehet (leven egy lib).
Mellesleg tamogatja a tobbsoros regexpet.
---------------------
AFPer: We've missed you, did you miss us?
Pratchett: Yes, but I think I have time to reload.
- A hozzászóláshoz be kell jelentkezni
Aham. Én nem vagyok otthon a C/C++ -ban, mindkét nyelvvel akadnak kisebb és nagyobb problémáim, és mindig oda lyukadunk ki, hogy akkor ezt az egész dolgot most hagyjuk.
Amiben megbízható tudásom van, az PHP, Perl, Python, Java, és egy kis C#.
Azt sem tudom, hogy a Java pl. milyen libet használ, használja-áe a PCRE libet, meg ilyenek.
- A hozzászóláshoz be kell jelentkezni
USE="nls nptl nptlonly unicode emacs bash-completion X gtk jpeg jpeg2k gif tiff wmf \
truetype png nsplugin alsa opengl gnome dvd dbus eds bzip2 dvdr qt3"
de gondolom a forras adott :)
--
Bow down and admit defeat. | Old, weak and obsolete.
- A hozzászóláshoz be kell jelentkezni
Pont ezt mondtam, hogy ez csak példa, a cél a vázolt probléma megoldása.
- A hozzászóláshoz be kell jelentkezni