Witam, mam takie dosyć nietypowe zadanie( nie jestem programistą, ale musze zaliczyć przedmiot). Otóż mam napisać program w pascalu, który zamieni pewnie słowa kluczowe w pliku źródłowym html (np do <html>, <a href..>, <a>
itp) doda pogrubienia też w języku html. Czyli otwieramy jeden plik i wszelkie zmiany zapisujemy do drugiego(gotowego) już pliku textowego. Przyznam szczerze, że szukałem już na googlach pomocy, ale tam zawsze jest jakiś prosty przykład z literkami, a nie ma już takiego bardziej złożonego o który mi właśnie chodzi. Mam taki problem, że mój program przenosi linijka po linijce ten stary, a nie mam pojęcia jak zrobić taką edycje, że jeśli napotka w tej linii na słowo kluczowe, to żeby je zmienił i szedł dalej. Pozdrawiam i czekam na jakieś ciekawe pomysły.
Najprostsze co mi przyszło do głowy
While not EoF(Plik_wej) do
begin
Readln(Plik_wej, Linia);
Linia := StringReplace(linia, 'html', '<html>', [rfReplaceAll]);
WriteLn(Plik_wyj);
end;
tylko tych Linia := StringReplace(linia, 'html', '<html>', [rfReplaceAll]); byś musiał sobie napisać tyle ile jest znaczników w htmlu.
Jeżeli już taka metoda jak powyżej, to lepiej z tablicą stałych z rekordem zawierającym pola z czego i na co zamienić. Tak bym pokombinował, zgodnie z zasadą DRY.
@kucher - skoro nie chcesz zostać programistą ( :] ) to raczej celuj w proste i czytelne rozwiązania, żebyś mógł łatwo zapamiętać; Oczywiście nie obejdzie się bez nauki - musisz poznać kilka procedur i funkcji, dzięki którym uda się napisać ten algorytm; Szkoda też, że nie pokazałeś kawałka tekstu, którzy program ma przetworzyć;
Przyznam szczerze, że szukałem już na googlach pomocy, ale tam zawsze jest jakiś prosty przykład z literkami, a nie ma już takiego bardziej złożonego o który mi właśnie chodzi.
Nie powinieneś szukać gotowego rozwiązania, tylko opisów procedur/funkcji, które pozwolą zamienić łańcuchy w tym bazowym;
Ramka kodu powinna wyglądać mniej więcej tak:
var
fInput, fOutput: TextFile;
strLine: AnsiString;
begin
AssignFile(fInput, 'C:\Input.txt');
AssignFile(fOutput, 'C:\Output.txt');
try
Reset(fInput);
ReWrite(fOutput);
while not EoF(fInput) do
begin
ReadLn(fInput, strLine);
// operacje zamieniające odpowiednie wyrażenia
WriteLn(fOutput, strLine);
end;
finally
CloseFile(fInput);
CloseFile(fOutput);
end;
end.
Oczywiście nazwy zmiennych dobierz sam, a nazwy plików ustaw na swoje; Możesz sobie napisać osobną procedurę przyjmującą w argumencie linię, która będzie obrabiana i zwracać już gotową do zapisu do pliku docelowego; Możesz to robić od razu, ale osobna procedura/funkcja zwiększy czytelność kodu;
Co do samej zamiany - nie wiem czy koledzy wyżej dobrze zrozumieli (a może ja nie zrozumiałem), ale zasada zamiany nie wygląda na tak oczywistą; Nie można podpiąć pod to zwykłej tablicy ze StringReplace, bo długość wyrażej, dla których odbędzie się ta zamiana nie jest zawsze znana:
który zamieni pewnie słowa kluczowe w pliku źródłowym html (np do
<html>
,<a href..>
,\<a>
itp)
Nie jest znana długość <a href..>
, więc ten element odpada; Według mnie należy przeszukiwać linię i sprawdzać każdy napotkany znacznik czy ma być zmodyfikowany czy nie, pobrać dynamicznie jego długość i tylko dodać znaczniki pogrubienia w odpowiednie miejsca zachowując oryginalny znacznik;
@kucher - jeśli chcesz, aby ktokolwiek Tobie pomógł to dokładnie opisz zasadę zamiany wyrażeń, bo na razie jak widać niewiele wiadomo i nieco błądzimy po omacku.
W sumie na dobrą sprawę to znaczników <a href...>
kolorować nie muszę. Mam tylko pokazać działanie czyli jak pozmieniam zwyczajne(określone znaczniki) to będzie super. A jeśli chodzi o przykladowy kod źródłowy to jest to obojętnie jaka strona w htmlu. Dziękuje za pomoc :P
dodanie znacznika `` - fp
Tak teraz patrzę na Twój pierwszy post i jeśli musisz zamieniać jedynie znaczniki ze stałą długością, to skorzystaj z podanej przeze mnie wcześniej konstrukcji i napisz dodatkową procedurę, w której dokonasz zmian na aktualnie wczytanej z pliku linii; Zadeklaruj sobie statyczną tablicę indeksowaną np. typem Boolean, w której umieścisz tyle wierszy, ile znaczników trzeba zamienić a w każdym wierszu wartość do odszukania (starą wartość) i wartość do wstawienia (nową wartość);
Przykładowe znaczniki:
znacznik do zamiany | znacznik po zamianie |
---|---|
<html> |
<b><html> |
</html> |
</html></b> |
... | ... |
Przykładowa tablica stałych: |
const
{ przykładowe znaczniki nie mające sensu pod względem składni html }
MARKERS: array [0 .. 3, Boolean] of AnsiString =
(
('<html>' , '<b><html>' ),
('</html>' , '</html></b>'),
('<p>' , '<b><p>'),
('</p>' , '</p></b>')
{... , ...}
);
Teraz w procedurze zamiany znaczników, w pętli stosujesz StringReplace jadąc po wszystkich wierszach tablicy podając do funkcji jako stary znacznik element spod False, a jako nowy spod True, np.:
const
STARY = False;
NOWY = True;
var
Linia: AnsiString;
IndeksZnacznika: Integer;
{...}
StringReplace(Linia, MARKERS[IndeksZnacznika, STARY], MARKERS[IndeksZnacznika, NOWY], [rfReplaceAll]);
Robisz to w pętli dla wszystkich znaczników do zamiany;
Nie musisz indeksować typem Boolean - można użyć typu całkowitoliczbowego lub zadeklarować sobie typ wyliczeniowy - do wyboru do koloru.