Wczytanie pliku ze stroną kodową ANSI

0

Cześć,
jestem trochę zielony a próbuję wczytać dane z pliku który ma stronę kodową w ANSI (z polskimi znakami) a następnie chcę go podzielić na mniejsze pliki gdzie znacznikiem dzielenia jest wyrażenie "</table>". Napisałem kod który dzieli plik na mniejsze pliki według założeń jednakże wczytywany plik jest ANSI a pliki wyplute rozjeżdżają się na polskich literach. Może ktoś pomóc?
Mam taki kod:

namespace FKDANEWESplit
{
    class Program
    {
        static void Main(string[] args)
        {
         
            string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            string plik = Path.Combine(path+"\\TEST", "TEST.txt");
            StreamReader sr = new StreamReader(plik);
            string pattern = @"</TABLE>";
            Regex rgx = new Regex(pattern);
            
            byte[] ciag = File.ReadAllBytes(plik);
            string content = Encoding.GetEncoding(1252).GetString(ciag);

          
            string[] result = rgx.Split(content);
            for (int ctr = 0; ctr < result.Length; ctr++)
            {
               Console.Write("{0}", result[ctr]);
               File.WriteAllText(plik + ctr, result[ctr]);
              
            }
             Console.ReadLine();
            }
        }
    }

ps. Plik z danymi ma postać:
<table=nazwa_tabeli1>
dane
dane

</table> <table=nazwa_tabeli2> dane dane </table> itd.....

Może ktoś mi podpowie jak dzielić plik po znaczniku z nazwą tabeli tak aby pliki wynikowe nazywały się jak nazwy tabel z której dane dany plik posiada ??

0

spróbuj zamienić

File.WriteAllText(plik + ctr, result[ctr]);

na

File.WriteAllText(plik + ctr, result[ctr], Encoding.ASCII);
0
neves napisał(a):

spróbuj zamienić

File.WriteAllText(plik + ctr, result[ctr]);

na

File.WriteAllText(plik + ctr, result[ctr], Encoding.ASCII);

Nic to nie zmieniło tak jak strona kodowa się rozjeżdżała tak rozjeżdża się nadal. Wydaje mi się że rozjazd zaczyna się już na wejściu bo po odpaleniu w oknie konsoli też już widać rozjazd.
Na załączonym zrzucie do góry jest widok z notepad++ ustawionym na ANSI a na dole widok z konsoli po odpaleniu programu

0

Pytanie brzmi czy chcesz wiedzę czy narzędzia?

0
Szalony Programista napisał(a):

Pytanie brzmi czy chcesz wiedzę czy narzędzia?

Przydało by się i to i to... kopniak w dobrą stronę też byłby dobry...

0

powinno śmigać tak jak chcesz:

    class Program
    {
        static void Main(string[] args)
        {
            string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            string plik = Path.Combine(path + "\\TEST", "TEST.txt");
       
      
            Regex rgx = new Regex(@"<table=(\w+)>(.*?)</table>");

        
            string content = File.ReadAllText(plik, Encoding.Default);

            MatchCollection result = rgx.Matches(content);
            for (int ctr = 0; ctr < result.Count; ctr++)
            {
                Console.Write("{0}", result[ctr]);
                string filePath = Path.Combine(path, "TEST", result[ctr].Groups[1].Value + ".txt");

                File.WriteAllText(filePath, result[ctr].Value, Encoding.Default);

            }
            Console.ReadLine();
        }
    }
0
neves napisał(a):

powinno śmigać tak jak chcesz:

            Regex rgx = new Regex(@"<table=(\w+)>(.*?)</table>");

Mógłbys mi trochę rozjaśnić tą linijkę bo muszę ją trochę przerobić bo coś jest chyba nie halo w tej linijce ponieważ program nic nie robi, zamieniłem ją na :```csharp

Regex rgx = new Regex(@"<TABLE=(\w+)>");

program się wykonał ale dostałem pliki z nazwą tak jak chciałem lecz wypełnione tylko tym znacznikiem. Pewnie dlatego że dane są wypisywane w nowych liniach plus znacznik po którym dzielimy jest trochę bardziej rozbudowany

<TABLE=Nazwa_tabeli, dodatkowe_stringi, dodatkowe_stringi, czasami_dodatkowe_stringi>
dane
dane
dane

</table>
0

Wielkość liter ma znaczenie, tutaj masz opisane dokładnie co każda konstrukcja oznacza:
https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-language-quick-reference

chcemy dopasować cały tekst od taga początkowego do zamykającego tabele:

<table=(\w+)>   // dopasowujemy tag otwierający, i łapiemy nazwę składającą się ze znaków występujących w wyrazie
(.*?)           // dowolny ciąg znaków pomiędzy tagami, jak najkrótszy
</table>        // tag zamykający

wersja ignorująca wielkosc liter

 Regex rgx = new Regex(@"<table=(\w+)>(.*?)</table>", RegexOptions.IgnoreCase);

a tu wersja na dodatkowe parametry po przecinku i ignorowanie nowych linii

Regex rgx = new Regex(@"<table=(\w+?)(\,.+)*>.*?</table>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
0

chcemy dopasować cały tekst od taga początkowego do zamykającego tabele:

<table=(\w+)>   // dopasowujemy tag otwierający, i łapiemy nazwę składającą się ze znaków występujących w wyrazie
(.*?)           // dowolny ciąg znaków pomiędzy tagami, jak najkrótszy
</table>        // tag zamykający

a tu wersja na dodatkowe parametry po przecinku i ignorowanie nowych linii

Regex rgx = new Regex(@"<table=(\w+?)(\,.+)*>.*?</table>", RegexOptions.IgnoreCase | RegexOptions.Singleline);

Wersja z dodatkowymi parametrami po przecinku (mam nadzieje że to że jest ich kilka nie ma wpływu) nie działa poprawnie tworzy się tylko jeden plik z nazwą pierwszej tabeli i ze wszystkimi danymi i innymi tabelami.

<table=(\w+?) // dopasowujemy tag otwierający, i łapiemy nazwę składającą się ze znaków występujących w wyrazie

co z powyższego wyrażenia odpowiada za "łapanie nazwy składającą się ze znaków występujących w wyrazie"? czy to że to pierwsza "część" dopasowania do wyrażenia regularnego?

(,.+)*

powyższe to dowolna ilość wystąpień konstrukcji ", dowolne_znaki"?

.*?

tutaj chyba muszę coś zmienić ponieważ tak jak widać poniżej dane są w nowych wierszach

<TABLE=Nazwa_tablicy,RC=0091177,UPDATE> \n
1 wiersz danych;\n
2 wiersz danych;\n
...
</TABLE>\n
<TABLE=Nazwa_tablicy2,RC=00000077,UPDATE> \n
1 wiersz danych;\n
2 wiersz danych;\n
...
</TABLE>\n

Ułożyłem coś takiego ale program się wykonuje i wykonuje i nie może się wykonać więc pewnie mam jakiś błąd

Regex rgx = new Regex(@"<TABLE=(\w+?)(\,.+)*>$(.*?$)*</TABLE>");
1

Spróbuj ten:

Regex rgx = new Regex(@"<table=(\w+?)(\,.+?)*>.*?</table>", RegexOptions.IgnoreCase | RegexOptions.Singleline);
0

Teraz poszło idealnie....
Przydałoby się jeszcze wyrzucić pierwszą i ostatnią linię.
próbowałem kombinować z linią:

File.WriteAllText(filePath, result[ctr].Value, Encoding.Default);

i zamieniłem na

File.WriteAllText(filePath, result[ctr].Groups[2].Value, Encoding.Default);

ale otrzymałem w plikach tylko ", UPDATE"
dla Groups[3] i wyżej otrzymywałem już tylko puste pliki

ps
<table=(\w+?) // dopasowujemy tag otwierający, i łapiemy nazwę składającą się ze znaków występujących w wyrazie

Co z powyższego wyrażenia odpowiada za "łapanie nazwy składającą się ze znaków występujących w wyrazie"? czy to że to pierwsza "część" dopasowania do wyrażenia regularnego?

0

jak przez linie rozumiesz tag

Regex rgx = new Regex(@"<table=(\w+?)(\,.+?)*>(.*?)</table>", RegexOptions.IgnoreCase | RegexOptions.Singleline);

i teraz zadziała result[ctr].Groups[3].Value

<table=    - początek otwierającego taga,żadnej magii tutaj nie ma
(\w+?)     - grupa o numerze 1, przechwytująca nazwę pliku, składającą z minimum jednego znaku (+) alfanumerycznego(\w), wersja niezachłanna (?)
(\,.+?)*   - grupa o numerze 2, przechwytująca pozostałe parametry, rozpoczynające się od przecinka (\,) a potem mające dowolny znak (.) minimum raz występujący(+) i możemy mieć wiele tych parametrów albo w ogóle (*)
>          - koniec taga otwierającego,żadnej magii tutaj nie ma
(.*?)      - grupa o numerze 3, składająca się z dowolnego znaku (.) występującego dowolną ilość razy(*), wersja niezachłanna (?)
</table>  - tak zamykający,żadnej magii tutaj nie ma
0

Już jest lepiej, w sensie w plikach są same dane jednakże każdy plik zaczyna się i kończy od pustej lini

1
aksimoN napisał(a):

Już jest lepiej, w sensie w plikach są same dane jednakże każdy plik zaczyna się i kończy od pustej lini

result[ctr].Groups[3].Value.Trim('\r', '\n' );
0

Szczerzę dziękuję za pomoc, mogę się zabierać za SSISa
pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1