@comtext/ocr-fix 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -0
- package/package.json +28 -0
- package/src/correct.js +68 -0
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# ocr-fix
|
|
2
|
+
|
|
3
|
+
Post-OCR коррекция текста — набор утилит для исправления артефактов, которые возникают при OCR-распознавании и мешают дальнейшей обработке текста.
|
|
4
|
+
|
|
5
|
+
## Что делает функция `correct`
|
|
6
|
+
|
|
7
|
+
Применяет набор исправлений, которые полезны после любого OCR:
|
|
8
|
+
|
|
9
|
+
| # | Исправление | Пример |
|
|
10
|
+
|---|---|---|
|
|
11
|
+
| 1 | Все пробельные символы кроме `\n` (табы, `\u00A0`, `\u202F` и др.) → обычный пробел | `"10 кг"` → `"10 кг"` |
|
|
12
|
+
| 2 | Перенос слова через дефис в конце строки: дефис и `\n` удаляются, части слова склеиваются | `"школь-\nного"` → `"школьного"` |
|
|
13
|
+
| 3 | Остальные одиночные `\n` внутри абзаца → пробел (двойные `\n` сохраняются) | `"строка\nпродолжение"` → `"строка продолжение"` |
|
|
14
|
+
| 4 | Дефис в роли тире → `—`: `--`, ` - `, а также дефис после `,` `.` `!` `?` `»` `)` | `"это - пример"` → `"это — пример"`, `"да,- нет"` → `"да, — нет"` |
|
|
15
|
+
| 5 | Кириллические буквы-двойники в отдельно стоящих римских цифрах → латинские | `"ХХ век"` → `"XX век"`, `"ХIХ"` → `"XIX"` |
|
|
16
|
+
| 6 | Пробел после точки в аббревиатурах и инициалах (буква + точка + буква/цифра) | `"В.И.Ленин"` → `"В. И. Ленин"`, `"т.1"` → `"т. 1"` |
|
|
17
|
+
| 7 | Несколько пробелов подряд → один пробел | `"слово слово"` → `"слово слово"` |
|
|
18
|
+
|
|
19
|
+
**Пример:**
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
Воспитание творческой активности учащихся в процессе изучения
|
|
23
|
+
ими математики является одной из актуальных целей нашего школь-
|
|
24
|
+
ного преподавания.
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
↓
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Воспитание творческой активности учащихся в процессе изучения ими математики является одной из актуальных целей нашего школьного преподавания.
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Установка
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
yarn add @comtext/ocr-fix
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Использование
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import { correct } from '@comtext/ocr-fix'
|
|
43
|
+
|
|
44
|
+
const rawOcrText = `Первый абзац\nиз двух строк\n\nВторой абзац`
|
|
45
|
+
console.log(correct(rawOcrText))
|
|
46
|
+
// "Первый абзац из двух строк\n\nВторой абзац"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Тесты
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
yarn test
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Для режима наблюдения (перезапуск при изменениях):
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
yarn test:watch
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Для отчёта о покрытии:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
yarn test:coverage
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Структура проекта
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
ocr-fix/
|
|
71
|
+
├── src/
|
|
72
|
+
│ └── correct.js # основная функция
|
|
73
|
+
├── tests/
|
|
74
|
+
│ └── correct.test.js # Jest-тесты
|
|
75
|
+
├── package.json
|
|
76
|
+
└── README.md
|
|
77
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@comtext/ocr-fix",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Post-OCR text correction utilities",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/correct.js",
|
|
7
|
+
"exports": "./src/correct.js",
|
|
8
|
+
"files": [
|
|
9
|
+
"src/"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"test": "node --experimental-vm-modules node_modules/.bin/jest",
|
|
13
|
+
"test:watch": "node --experimental-vm-modules node_modules/.bin/jest --watch",
|
|
14
|
+
"test:coverage": "node --experimental-vm-modules node_modules/.bin/jest --coverage"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"ocr",
|
|
18
|
+
"text",
|
|
19
|
+
"correction"
|
|
20
|
+
],
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"jest": "^29.7.0"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/src/correct.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Корректирует текст после OCR-распознавания.
|
|
3
|
+
*
|
|
4
|
+
* Применяемые исправления:
|
|
5
|
+
* 1. Все пробельные символы кроме \n (табы, неразрывные пробелы и др.) → обычный пробел.
|
|
6
|
+
* 2. Перенос слова в конце строки (строка заканчивается на «-»): дефис и \n
|
|
7
|
+
* удаляются, части слова склеиваются («школь-\nного» → «школьного»).
|
|
8
|
+
* 3. Остальные одиночные \n внутри абзаца → пробел (двойные \n сохраняются).
|
|
9
|
+
* 4. Дефис в роли тире → em dash «—»:
|
|
10
|
+
* a. «--» (двойной дефис) → «—»
|
|
11
|
+
* b. Дефис после знака препинания: «,- », «.- », «? - » и т.п. → «знак — »
|
|
12
|
+
* c. Дефис между пробелами: « - » → « — »
|
|
13
|
+
* 5. Кириллические буквы-двойники в римских цифрах заменяются на латинские
|
|
14
|
+
* («ХХ» → «XX», «ХIХ» → «XIX»). Срабатывает только на отдельно стоящих токенах,
|
|
15
|
+
* не являющихся частью кириллического слова.
|
|
16
|
+
* 6. Пробел после точки в аббревиатурах и инициалах: буква + точка + (буква или цифра)
|
|
17
|
+
* без пробела → добавить пробел («В.И.Ленин» → «В. И. Ленин», «т.1» → «т. 1»).
|
|
18
|
+
* 7. Несколько пробелов подряд → один пробел.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} str - Входной текст после OCR
|
|
21
|
+
* @returns {string} Скорректированный текст
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// Кириллические символы, визуально совпадающие с символами римских цифр
|
|
25
|
+
const CYR_TO_LAT = { 'Х': 'X', 'х': 'x', 'С': 'C', 'с': 'c', 'М': 'M', 'м': 'm', 'І': 'I', 'і': 'i' }
|
|
26
|
+
const CYR_ROMAN_RE = /[ХхСсМмІі]/
|
|
27
|
+
|
|
28
|
+
function correct(str) {
|
|
29
|
+
// 1. Все пробельные символы кроме \n → обычный пробел
|
|
30
|
+
str = str.replace(/[^\S\n]/g, ' ')
|
|
31
|
+
|
|
32
|
+
// 2. Перенос слова: «-\n» (не перед концом строки/файла и не перед пустой строкой) → «»
|
|
33
|
+
str = str.replace(/-\n(?!($|\n))/g, '')
|
|
34
|
+
|
|
35
|
+
// 3. Остальные одиночные \n → пробел (двойные \n сохраняются)
|
|
36
|
+
str = str.replace(/(?<!\n)\n(?!($|\n))/g, ' ')
|
|
37
|
+
|
|
38
|
+
// 4a. Двойной дефис → em dash
|
|
39
|
+
str = str.replace(/--/g, '—')
|
|
40
|
+
|
|
41
|
+
// 4b. Дефис после знака препинания (с опциональным пробелом перед ним) → «знак — »
|
|
42
|
+
// Охватывает: «,- », «.- », «!- », «?- », «»- », «)- » и варианты с пробелом до дефиса
|
|
43
|
+
str = str.replace(/([,.:;!?»\)]) ?- /g, '$1 — ')
|
|
44
|
+
|
|
45
|
+
// 4c. Одиночный дефис между пробелами → em dash
|
|
46
|
+
str = str.replace(/ - /g, ' — ')
|
|
47
|
+
|
|
48
|
+
// 5. Кириллические двойники в римских цифрах → латинские
|
|
49
|
+
// Токен: только символы римских цифр (Latin или Cyrillic-lookalike),
|
|
50
|
+
// не окружён кириллическими/латинскими буквами, цифрами или точкой.
|
|
51
|
+
str = str.replace(
|
|
52
|
+
/(?<![а-яёА-ЯЁa-zA-Z0-9.])[IVXLCDMivxlcdmХхСсМмІі]+(?![а-яёА-ЯЁa-zA-Z0-9])/g,
|
|
53
|
+
(match) => {
|
|
54
|
+
if (!CYR_ROMAN_RE.test(match)) return match
|
|
55
|
+
return match.replace(/[ХхСсМмІі]/g, ch => CYR_TO_LAT[ch])
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
// 6. Аббревиатуры и инициалы: буква + точка + (буква или цифра) без пробела → добавить пробел
|
|
60
|
+
str = str.replace(/([а-яёА-ЯЁa-zA-Z])\.(?=[а-яёА-ЯЁa-zA-Z0-9])/g, '$1. ')
|
|
61
|
+
|
|
62
|
+
// 7. Несколько пробелов подряд → один пробел
|
|
63
|
+
str = str.replace(/ {2,}/g, ' ')
|
|
64
|
+
|
|
65
|
+
return str
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export { correct }
|