Xappe skrev:
Känner du att du har tid till övers får du gärna gå igenom de reguljära uttrycken i lite mer detalj. Såvida det inte är helt perlspecifikt vill säga.

Bakgrund: Det finns olika syntax för reguljära uttryck (regex). Det man vanligen menar är unix-regex, men det finns andra syntaxer i t.ex yacc och omnimark. Även unix-regex är inte exakt samma överallt. Den i
grep är mer basic och inte kompatibel med den i
egrep som i sin tur inte är helt kompatibel med den i
emacs. Regex i
perl,
java och
python är alla utökade regex och rätt så lika. Är inte säker men jag tror att regex i
awk är ganska nära den i egrep och regex i
sed är mer lik den i grep fast mer kraftfull än den i awk.
Förutom regex:arna så kan lite av grekiskan runtomkring behöva förklaras. Det blir väldigt perl-specifikt.
Förklaringar
$word2 =~ s/aaa/bbb/g perl-uttryck för att i variabel $word2 byta ut alla "aaa" till "bbb". Vänsterledet (aaa) är regex och högerledet (bbb) är bara en sträng. "g"(=global) för att byta
alla förekomster av "aaa", inte bara första.
Rad 57: $word2
=~ s/([^\w])/sprintf("%%%X",ord($1))/ge;
"\w" (word constituent) matchar ett alfanumeriskt tecken.
"^" efter "[" är invers. "[^\w]" matchar alla tecken
utom alfanumeriska, ett tecken.
"(" och ")" bildar en grupp och gör att texten som matchar sparas i "$1".
Det sista "e" (evaluate) betyder att högerledet inte är en sträng utan ett uttryck som ska evalueras och som returnerar en sträng. Här körs sprintf "%%%H" för att formatera ett hex-tal. "%%" blir "%" och "%H" blir t.ex "F6". "ord" tar ascii-värdet av "$1", tecknet som matchade.
m/regex/ kan även skrivas
/regex/ och betyder sök efter regex i variabel $_. (m=match)
Rad 67:
if (/0 synonymer hittades/) {
Variabel $_ är automatisk loop-variabel i while(<FH>). Testar om angiven text finns i senast inlästa block från filen.
Rad 72:
if (/class="ord">(.*?)</i) {
Letar i $_ efter ett avsnitt som börjar med "class="ord">" och slutar med "<". Mellanledet ".*?" matchar 0 eller flera vadsomhelst. Skillnaden med ".*" är att ".*?" försöker matcha så lite som möjligt, så efterföljande "<" är den
första "<" som matchar. "(" ")" sparar texten som matchar ".*?" i variabeln "$1". "i" i slutet betyder ignore case.
Rad 76: if (/
class="synonym">(.*)<\/tr/i
m) {
Ungefär som ovan. Matchningen slutar vid första förekomsten av "</tr". "m" (multiple line) kanske är ett feltänk från min sida. Kanske ska vara "s" (single line).
Rad 79: $def
=~ s/<(\/?\w+).*?>/($tagmap{lc($1)}||"")/eg;
Sök i variabel $def efter en html-tag "<...>". "\/" matchar "/". "?" betyder 0 eller 1 antal. Altså 0 eller 1 "/". "\w+" är 1 eller flera alfanumeriska. ".*?" är 0 eller flera vadsomhelst. "(" ")" sparar de alfanumeriska med ev inledande "/" i variabel "$1". "e" gör att högerledet evaluaras. Om det är en träff på en tagg, slå upp $1 i hashtabell "tagmap". Om det inte blev träff i hashtabellen använd alternativet efter "||", tom sträng. "lc" gör om till lower case, så både "B" och "b" känns igen som html-tagg för bold. Sista "g" (global) för att gå igenom hela $def och inte stanna efter första träffen.
Enkelt va?