Транслятор не распознает Match

Здравствуйте! Делаю первые шаги. Поставил с сборку3268 на свою Виндовс10. Читаю статью Регулярно выражаемся . Первые два примера с foreach получилось и странслировать и выполнить. Но в третьем транслятору не нравится слово Match. Подскажите, почему? Исходник: {$codepage utf8} uses System; uses System.Text.RegularExpressions;

const filenameinp = ‘123.txt’; filenameotp = ‘1234.txt’;

var s, s1: string; fi, fo: text; i: integer; DefaultEncoding := Encoding.UTF8;

begin Reset(fi, filenameinp, DefaultEncoding); Rewrite(fo, filenameotp, DefaultEncoding); i := 0; while not Eof(fi) do begin readln(fi, s); foreach s0: string in s.Split(new char[1](’ ‘), StringSplitOptions.RemoveEmptyEntries) do Writeln(s0); foreach s0: string in Regex.Split(s, ’ +’) do Writeln(s0); foreach m: Match in Regex.Matches(s, ‘\w+’) do Write(m.Index); writeln(fo, s); inc(i); end;
close(fi); close(fo); end. З.Ы. При копировании текста программы отсюда в среду разработки апострофы, обрамляющие строки, у меня стали почему-то другими и пришлось поменять их вручную.

Используйте фичи markdown. В данном случае чтобы выделять код:

```
код
ещё строка
```

Получается:

код
ещё строка

А то как вы вставили нечитаемо…

И ещё, что вы назваете транслятором?

…что вы назваете транслятором? Вот эту среду разработки:

Пытаюсь разобраться с “фичами markdown”, чтобы вставить исходник.

Интегрированная среда разработки (IDE) это текстовый редактор, присыпанный поверх фичами для удобств написания кода.

Когда вы нажимаете компилировать или выполнить - IDE запускает вам ещё 1 программу, которая называется компилятор, создающую из текста программы бинарный (обычно .exe) файл.

А трансляторы это программы подобные компиляторам, но вместо бинарников создающие текст программы на другом, более низкоуровневом языке. Для PascalABC.Net таких программ, на сколько я знаю, никто не делал.


У вас скриншот слипся с цитатой меня, потому что надо всегда оставлять пустую строчку между разными частями текста.
А вообще вы можете выделить часть моего сообщения и нажать всплывающую кнопку “цитировать”.

Символ ` находится там же где русская Ё, но в англ. раскладке. Я вам уже привёл выше пример как его использовать чтобы выделять код.

У вас справа показывает предпросмотр. Не обязательно постить чтобы проверить что работает.

Извините великодушно! Я новичок на форуме и не только на этом. 1 Оказывается, выделить мышью текст программы в IDE, затем Сtrl-С и Ctrl-V в пост - нельзя. Где на клавиатуре буква Ё, я знаю, но увы, не знаю, что еще и в какой последовательности нажать. 2 Что нажать, чтобы увидеть справа предпросмотр?

{utf8} 
uses System; 
uses System.Text.RegularExpressions;
const filenameinp = '123.txt'; 
filenameotp = '1234.txt';
var s, s1: string; 
   fi, fo: text; 
        i: integer; 
DefaultEncoding := Encoding.UTF8;

begin 
Reset(fi, filenameinp, DefaultEncoding); 
Rewrite(fo, filenameotp, DefaultEncoding);
 i := 0; 
 while not Eof(fi) do 
   begin readln(fi, s); 
   foreach s0: string in s.Split(new char[1](' '), StringSplitOptions.RemoveEmptyEntries) do Writeln(s0); 
   foreach s0: string in Regex.Split(s, ' +') do Writeln(s0); 
   foreach m: Match in Regex.Matches(s, '\w+') do Write(m.Index); 
   writeln(fo, s); 
   inc(i);
   end;
close(fi);
 close(fo); 
 end.

Можно. Только выделять лучше с Ctrl+A, а не мышкой.

Всмысле в последовательности? Я вот тут показал пример как выделять код и как он будет выглядеть.

Вообще он вам сразу показываться должен, пока вы пишете ответ. Пришлите скриншот как у вас окно ответа выглядит, что ли…

Кажется, получилось вставить исходник. Если вставить его в IDE и нажать F9, то выдается ошибка “Встречено Match, а ожидалось выражение”. Не кушает среда это слово. Подскажите, почему?

Ту статью что вы кинули писали очень давно… С того момента ввели конструкцию match:

##
procedure Test(o: object);
begin
  match o with
    integer(var i): $'Передали целое={i}'.Println;
    string(var s): $'Передали строку="{s}"'.Println;
    else $'Передали что то другое: {_ObjectToString(o)}'.Println;
  end;
end;

Test(5);
Test('abc');
Test(3.5);
Test(new class(x:=5,s:='d'));

В вашем случае match считает ключевым словом, вместо названия. Можно использовать &Match, таким образом экранируя.

Только непонятно зачем тут вообще писать имя типа. Пишите foreach var m in ...

Вообще код может быть ещё на много более читабельным…
Я сам в начале не понимал на сколько важно правильно форматирова код (отступы пробелами слева и т.п.), но пока для себя не разберётесь - хотя бы используйте авто-форматирование, чтобы у людей читающих ваш код глаза не вытекали…
В IDE есть кнопка справа от кнопки компиляции и ещё одна под ПКМ, “Форматировать код”.

Это комментарий, он ничего не делает. А директива $codepage которую вы выше пытались использовать не существует.

Текст программы всегда сохраняется в кодировке UTF8+BOM. А кодировка стандартных строк и символов во время выполнения всегда UTF16.

В системном модуле (PABCSystem) уже есть такая переменная. Из за того что вы объявили новую с тем же именем - вы себе спрятали ту, которая используется по-умолчанию (хотя к ней всё ещё можно обращаться как PABCSystem.DefaultEncoding).

Перенесите это присвоение внутрь begin-end, тогда DefaultEncoding не надо будет передавать в Reset и т.п.

И лучше вообще выкинуть var до begin. Делать свалку переменных до begin это очень старая и в наше время презираемая практика - провоцирует добавление багов по глупости.

var надо ставить как можно ближе к первому использованию переменной.
К примеру:

begin
  var fi: TextFile;
  Reset(fi, filenameinp);
  ...

Или ещё лучше:

var fi := OpenRead(filenameinp);

Но в данном случае вам не нужно паскальное чтение по лексемам:

// Прочитать (и вывести) 1 число
fi.ReadInteger.Println;
// Прочитать ещё 1 число (на следующей строчке если предыдущая кончилась)
// И раз ln - значит затем ещё пропустить все символы до конца строчки
fi.ReadlnInteger.Println;

Вы читаете весь файл по 1 строке и только 1 раз - лучше вместо доп. переменной-файла использовать ReadLines:

foreach var l in ReadLines(filenameinp) do

Спасибо огромное за ответ. Вот только мне , чтобы в нем разобраться, надо расти и расти. Подскажите, можно ли использовать возможности pascalABC.net, предназдачанные для работы с регэкспами, не зная классы, методы и прочуюю премудрость ООП? А если нельзя, то не подскажете ли какой-нибудь учебник? Нужно, в первую очереедь, для разработки программы - анализатора текстов и исправления ошибок в них, т.е. хорошо бы с регэкспами.

В [1] можно не указывать количество - оно и так известно из (' ').

new char[](' ')

И тип элементов массива тоже можно дать компилятору автоматически вычислить - останется всего-лишь:

|' '|

А ещё есть

s.ToWords(' ')

Оно вызывает Split всегда с параметром StringSplitOptions.RemoveEmptyEntries.

ООП надо знать чтобы писать свои типы данных. Чтобы использовать методы надо знать методы а не ООП. Когда вы ставите точку после имени переменной определённого типа - IDE вам показывает всё, что можно со значением этого типа делать. И почти у всего есть описания.

Ну, книги есть на сайте pascalabc.net - но по моему тут больше нужен комбинированный подход, и в первую очередь - опыт. То есть писать и думать/слушать что можно лучше.

Мне доставляет расписывать придирки по коду… По краней мере пока их слушают.
Но это наверное проще и быстрее будет в формате чата:

Что касается лично регекса - с ним важно отзывчивость при тестировании, чтобы понимать что не так.
Я обычно использую этот сайт: https://regex101.com/
Там сразу документация для всех элементов.
Не забудьте выбрать диалект для .Net чтобы работало так же как в вашей программе.

Ну и он хорош для простых случаев, но если попытаетесь решать им сложную проблему - у вас будет 2 проблемы. В этом случае стоит задуматься о том, чтобы парсить текст вручную…

Анекдот про регэксы и две проблемы уже знаю :slight_smile: На “устаревшую” статью я и набрел, разыскивая подходящий инструмент, что бы не нужно было применять к каждому тексту вручную, по очереди десятки разных регэксов для выпиливания разных видов ошибок. Оказывается, Паскаль, который я осваивал в 90-е, совсем не умер, а наоборот, умеет регэксы! Надеялся, что мне хватит тех возможностей, которые в статье описывались, в 90% случаев. Жаль, что нет более новой статьи. Еще раз спасибо!

Ну, тот что был в 90-е таки умер. Данный паскаль относится к древнепаскальным диалектам примерно так же как C# к C. Название похожее, и базовый синтаксис тот же. Но код по совсем другим принципам пишется и выполняется.

Здравствуйте! На ту же тему, но теперь дело явно не в старой статье. Во встроенном в IDE справочнике по языку я увидел метод LastIndexOf(s: string): integer и захотел им воспользоваться (см. ниже). Компилятор на LastIndexOf споткнулся, говорит «Неизвестное имя». За древние подходы к написанию – простите великодушно.

Вопрос 1. Правильно ли я понимаю, что надо при помощи uses указать нужное пространство имен?

Вопрос 2. Если да, то как, откуда узнать имя этого пространства?

uses System;
const
  filenameinp = '123.txt';
  filenameotp = '1234.txt';
var
  s: string;
  fi, fo: text;
  j: integer;
  DefaultEncoding := Encoding.UTF8;
begin
  Reset(fi, filenameinp, DefaultEncoding);
  Rewrite(fo, filenameotp);
  while not Eof(fi) do
  begin
    readln(fi, s);
    writeln(s);
    j:=LastIndexOf('ЛЕХИН');
    writeln(fo, s);
    end;  
  close(fi);
  close(fo);
end.

Нет, неправильно понимаете. Давайте так:
В выражении LastIndexOf('ЛЕХИН');, где вы указали, в какой переменной вы ищите эту подстроку?

Может всё же вы хотя бы попробуете писать по-современному? И то как вы присваиваете DefaultEncoding это даже не устаревший стиль, а логически неправильно.

В выражении LastIndexOf('ЛЕХИН'); , где вы указали, в какой переменной вы ищите эту подстроку? Нигде не указал, т.к. из описания метода LastIndexOf не понял что такое текущая строка. Надеялся, что это станет понятно позднее. DefaultEncoding := Encoding.UTF8 помогло мне заставить программу понять, что исходный файл ‘123.txt’ имеет кодировку UTF8. Результирующий ‘1234.txt’ должен иметь такую же.