Pull to refresh

Comments 11

addWords: true

Господи, ну нет этой опции, она сто лет как была deprecated и удалена. Зачем вы её тянете из старых статей? Или вы просто накалдырили статью ллм-кой по-быструхе?

Люблю Хабр за культуру комментирования :)

Примеры взяты из моей конфигурации, которую я собирал довольно давно. Ошибки при запуске не возникают, так что я и не перепроверял.

  1. Пример конфигурационного файла cspell.json из официальной документации:

    {
    "$schema": "
    https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
    "version": "0.2",
    "dictionaryDefinitions": [
    {
    "name": "project-words",
    "path": "./project-words.txt",
    "addWords": true
    }
    ],
    "dictionaries": ["project-words"],
    "ignorePaths": ["node_modules", "/project-words.txt"]
    }

  2. Пользовательские определения по словарю, в котором одно из полей (барабанная дробь) — addWords. Опять же из официальной документации.

О, спасибо, я тоже не знал что addWords уже не используется. Респект!

По моему опыту ревью, неправильное написание слов встречаются не чаще, а то и реже, чем очевидно несогласованные формы, забытые после переделки предложений слова и ошибки пунктуации. Есть ли оффлайн-инструменты против этого?

Согласен с вашей оценкой. В статье я упоминаю LanguageTool, он на это способен. Но я его только тестировал, поэтому мне мнение не является достаточно авторитетным.

Мне показалось, что его качество проверок у него довольно нестабильное, и я не смог понять, как это качество повысить. Писать длинные правила в XML — то еще удовольствие.

Также он оказался лично для меня довольно сложным в конфигурации и требователен к ресурсам. То есть ничего невозможного, но я решил не вкладываться в это с учетом не устраивающего меня качества проверок. Вероятно, сейчас я справился бы с настройкой и адаптацией под свои процессы лучше, в момент тестирования LanguageTool я знал и умел намного меньше чем сейчас.

Ну и с какого-то года все для локального использования пользуются форками из-за изменения лицензии оригинального LanguageTool, а LibreGrammar вроде бы лучший из них.

Лично я бы смотрел в сторону небольших опенсорсных моделей нейросетей типа Gemma, которые можно развернуть у себя или в корпоративной контуре. Думаю, что через пару лет в сообществе накопится достаточно экспертизы, чтобы строить на их основе прикладные решения. По моему опыту, модели неплохо умеют проверять текст уже сейчас, проблемы в основном в стабильности и предсказуемости результатов и в интерфейсах для доступа к моделям.

Из любопытного: в cSpell есть настройка checkLimit, которая указывает сколько килобайт файла спеллчекать. И по умолчанию она установлена в 500. Что на больших .md'шках может легко не хватить и возникает криповая ситуация, когда часть файла спеллчекер проверяет, а часть — нет. И никаких ошибок или варнингов в консоли VSCode. Мне пришлось покопаться в сорцах расширения VSCode и потом cSpell, чтобы обнаружить эту настройку 😳

```[\\s\\S]*```

У вас в примерах местами жадный квантификатор, а местами нет. Просто * будет пытаться вобрать в себя наиболее длинное вхождение, что чревато O(n²) и всплывет лишь на длинных файлах.

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

Как бы вы предложили изменить эти регулярки? Возьмем для примера ту, которую вы процитировали. В блоке кода может быть любое количество любого кода, мы заранее не знаем ни о его языке, ни о синтаксисе, ни об объеме.

Как стоит описывать с помощью регулярок такие фрагменты?

концепцией алгоритмической сложности

Я лучше чем https://www.regular-expressions.info/catastrophic.html не объясню. Но вкратце: O(n^2) значит, что при возросшей длине текста куда быстрее возрастает сложность, НО это не проявляется, пока движку не пришлось делать backtracking (идти назад и пробовать-перебробывать по символу).

И при этом я забыл сказать про логическую ошибку здесь:

```[\\s\\S]*```

Звездочка greedy - как можно больше захапать. Если с первым вхождением проблем нет, но последнее оно будет искать вплоть до конца документа. И возьмет самое последнее. То есть при двух блоках кода в документе исключается с первого открывающегося апострофа (перепрыгивая конец первого блока) по последний закрывающийся апостроф.

А нам нужно закрыться как можно раньше, при первом повторном тройном апострофе. Делаем non-greedy через *? и оно шурует только до ближайщего тройного апострофа.

Тестовый текст:

head of file

```
code
```

docs text

```
code2
```

end of file

https://regex101.com/r/GpxWEi/1 - дублирую для надежности (+ режим "точка как новая строка"):

/```(.*)```/s

Жадный вариант со звездочкой берет от жизни всё. В том числе промежуточный не-код:

```
code
```

docs text

```
code2
```

А теперь нежадный (+режим глобальный, чтобы все вхождения по ходу документа искал) - https://regex101.com/r/oDjqRX/1:

/```(.*?)```/gs
```
code
```
```
code2
```

Текст посередине не пострадал, выцепил только кодовые блоки.

Справа есть хорошая справка и объяснения.

Потом пройдитесь с Regex Debugger (слева) на одиночном блоке и обеими регулярками. Жадной надо на 3 шага больше, чем нежадной, потому что она начинает backtracking на апострофах каждый раз. Если бы была регулярка потяжелее, как описано в мною упомянутой статье, то там бы уже проблема скорости исполнения стала в полный рост.

И хорошо, что я на эту статью напал до того, как у себя нескончаемую регулярку устроил :) Хотя бы сразу знал, где перечитать и как менять.

По вашим примерам как ПОТЕНЦИАЛЬНЫЕ места (вчитываться надо... когда "если работает - ..."):

  1. // Code blocks with indentation из Sphinx+rST

  2. // JSX/HTML из Docusaurus - тут, вроде бы наоборот, надо жадную звезду оставить, т.к. других символов кроме угловых скобок не встречается.

Спасибо за такой развернутый анализ , мне тут определенно есть над чем подумать и что потестировать.

Sign up to leave a comment.

Articles