tr-adres 0.1.0__tar.gz
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.
- tr_adres-0.1.0/CHANGELOG.md +24 -0
- tr_adres-0.1.0/CITATION.cff +20 -0
- tr_adres-0.1.0/LICENSE +21 -0
- tr_adres-0.1.0/MANIFEST.in +10 -0
- tr_adres-0.1.0/PKG-INFO +315 -0
- tr_adres-0.1.0/README.md +277 -0
- tr_adres-0.1.0/pyproject.toml +123 -0
- tr_adres-0.1.0/setup.cfg +4 -0
- tr_adres-0.1.0/src/tr_adres/__init__.py +85 -0
- tr_adres-0.1.0/src/tr_adres/__main__.py +7 -0
- tr_adres-0.1.0/src/tr_adres/_sozluk.py +62 -0
- tr_adres-0.1.0/src/tr_adres/cli.py +160 -0
- tr_adres-0.1.0/src/tr_adres/data/gazetteer.json +1 -0
- tr_adres-0.1.0/src/tr_adres/formatter.py +96 -0
- tr_adres-0.1.0/src/tr_adres/gazetteer.py +349 -0
- tr_adres-0.1.0/src/tr_adres/metin.py +124 -0
- tr_adres-0.1.0/src/tr_adres/model.py +82 -0
- tr_adres-0.1.0/src/tr_adres/pandas_ext.py +62 -0
- tr_adres-0.1.0/src/tr_adres/parser.py +1021 -0
- tr_adres-0.1.0/src/tr_adres/py.typed +0 -0
- tr_adres-0.1.0/src/tr_adres.egg-info/PKG-INFO +315 -0
- tr_adres-0.1.0/src/tr_adres.egg-info/SOURCES.txt +35 -0
- tr_adres-0.1.0/src/tr_adres.egg-info/dependency_links.txt +1 -0
- tr_adres-0.1.0/src/tr_adres.egg-info/entry_points.txt +2 -0
- tr_adres-0.1.0/src/tr_adres.egg-info/requires.txt +9 -0
- tr_adres-0.1.0/src/tr_adres.egg-info/top_level.txt +1 -0
- tr_adres-0.1.0/tests/blind.py +248 -0
- tr_adres-0.1.0/tests/corpus.py +580 -0
- tr_adres-0.1.0/tests/test_cli.py +147 -0
- tr_adres-0.1.0/tests/test_corpus.py +38 -0
- tr_adres-0.1.0/tests/test_doctests.py +33 -0
- tr_adres-0.1.0/tests/test_formatter.py +81 -0
- tr_adres-0.1.0/tests/test_gazetteer.py +193 -0
- tr_adres-0.1.0/tests/test_metin.py +110 -0
- tr_adres-0.1.0/tests/test_pandas.py +48 -0
- tr_adres-0.1.0/tests/test_parser.py +104 -0
- tr_adres-0.1.0/tools/build_gazetteer.py +119 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-11-08
|
|
8
|
+
### Added
|
|
9
|
+
- `parse(text) -> Adres`: rule-based parser for free-text Turkish postal addresses: il, ilçe,
|
|
10
|
+
mahalle, köy, cadde/bulvar/yol/meydan and sokak/çıkmaz (with type), site, apartman, blok,
|
|
11
|
+
bina no, kat, iç kapı/daire no, posta kodu, plus `confidence`, the unparsed remainder
|
|
12
|
+
(`kalan`) and a list of corrections and inferences (`notlar`).
|
|
13
|
+
- Abbreviations (`mah. mh. cad. cd. sok. sk. bulv. blv. no: d: k: kat apt. blk. sit.` …),
|
|
14
|
+
Turkish casing, ASCII-folded input, typo-tolerant province/district matching (bounded
|
|
15
|
+
Damerau-Levenshtein), arbitrary component order, `No:12/3` building/flat numbers,
|
|
16
|
+
numbered streets (`1203/2 Sk.`), floors and blocks, labelled forms, postal codes.
|
|
17
|
+
- `normalize(text)` and `format(adres, style="kargo"|"resmi")`.
|
|
18
|
+
- Gazetteer of all 81 provinces with plate codes and 973 districts with PTT postal-code
|
|
19
|
+
ranges (`il_bul`, `ilce_bul`, `ilce_ara`, `plaka`, `is_valid_ilce`, `merkez_ilce`,
|
|
20
|
+
`posta_kodu_il`, `posta_kodu_ilceler`, `iller`, `ilceler`, `kaynak`).
|
|
21
|
+
- Turkish string helpers: `tr_lower`, `tr_upper`, `tr_title`, `ascii_fold`, `edit_distance`.
|
|
22
|
+
- `parse_many` and the `tr-adres` command (`parse` / `normalize`, text, stdin or CSV in →
|
|
23
|
+
CSV out).
|
|
24
|
+
- Optional pandas accessor `Series.tradres` (`pip install "tr-adres[pandas]"`).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite it as below."
|
|
3
|
+
authors:
|
|
4
|
+
- family-names: "Eminoğlu"
|
|
5
|
+
given-names: "Yusuf"
|
|
6
|
+
email: "yusufeminoglu@gmail.com"
|
|
7
|
+
orcid: "https://orcid.org/0009-0005-6000-2934"
|
|
8
|
+
title: "tr-adres"
|
|
9
|
+
version: "0.1.0"
|
|
10
|
+
date-released: "2026-11-08"
|
|
11
|
+
license: "MIT"
|
|
12
|
+
repository-code: "https://github.com/YusufEminoglu/tr_adres_sdk"
|
|
13
|
+
url: "https://pypi.org/project/tr-adres/"
|
|
14
|
+
abstract: "Parser and normaliser for Turkish postal addresses with a bundled gazetteer of the 81 provinces and 973 districts of Türkiye."
|
|
15
|
+
keywords:
|
|
16
|
+
- turkish
|
|
17
|
+
- address parsing
|
|
18
|
+
- address normalization
|
|
19
|
+
- gazetteer
|
|
20
|
+
- data cleaning
|
tr_adres-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yusuf Eminoğlu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
include CHANGELOG.md
|
|
4
|
+
include CITATION.cff
|
|
5
|
+
include pyproject.toml
|
|
6
|
+
include src/tr_adres/py.typed
|
|
7
|
+
recursive-include src/tr_adres *.py
|
|
8
|
+
recursive-include src/tr_adres/data *.json
|
|
9
|
+
recursive-include tests *.py
|
|
10
|
+
recursive-include tools *.py
|
tr_adres-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tr-adres
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Parse and normalise Turkish postal addresses: il, ilçe, mahalle, street, building and flat numbers, with a bundled gazetteer of all 81 provinces and 973 districts.
|
|
5
|
+
Author-email: Yusuf Eminoğlu <yusufeminoglu@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/YusufEminoglu/tr_adres_sdk
|
|
8
|
+
Project-URL: Repository, https://github.com/YusufEminoglu/tr_adres_sdk
|
|
9
|
+
Project-URL: Issues, https://github.com/YusufEminoglu/tr_adres_sdk/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/YusufEminoglu/tr_adres_sdk/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: turkish,turkey,turkiye,address,address-parser,address-normalization,adres,il,ilce,mahalle,postal-code,posta-kodu,gazetteer,geocoding,data-cleaning,logistics,e-commerce,nlp
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Natural Language :: Turkish
|
|
21
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
23
|
+
Classifier: Topic :: Office/Business
|
|
24
|
+
Classifier: Intended Audience :: Developers
|
|
25
|
+
Classifier: Intended Audience :: Science/Research
|
|
26
|
+
Classifier: Typing :: Typed
|
|
27
|
+
Requires-Python: >=3.9
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Provides-Extra: pandas
|
|
31
|
+
Requires-Dist: pandas>=1.3.0; extra == "pandas"
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
35
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
36
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
# tr-adres
|
|
40
|
+
|
|
41
|
+
[](https://pypi.org/project/tr-adres/)
|
|
42
|
+
[](https://pypi.org/project/tr-adres/)
|
|
43
|
+
[](LICENSE)
|
|
44
|
+
|
|
45
|
+
**Türkçe posta adreslerini ayrıştırma ve standartlaştırma kütüphanesi** · *Parse and normalise
|
|
46
|
+
Turkish postal addresses* — saf Python, bağımlılıksız, 81 il ve 973 ilçelik gömülü sözlükle.
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
>>> import tr_adres
|
|
50
|
+
>>> tr_adres.normalize("caferaga mh moda cd no 12 d 3 kadikoy istanbul")
|
|
51
|
+
'Caferağa Mah. Moda Cad. No:12 D:3 Kadıköy/İstanbul'
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
[Türkçe](#türkçe) · [English](#english)
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Türkçe
|
|
60
|
+
|
|
61
|
+
E-ticaret ödeme formları, kargo etiketleri ve CRM kayıtlarındaki serbest metin adresleri
|
|
62
|
+
bileşenlerine ayırır (il, ilçe, mahalle, cadde/sokak, bina no, kat, daire, site/apartman/blok,
|
|
63
|
+
posta kodu), yazım hatalarını ve ASCII yazımı düzeltir, tek satırlık standart biçime çevirir.
|
|
64
|
+
|
|
65
|
+
### Kurulum
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install tr-adres # yalnızca standart kütüphane
|
|
69
|
+
pip install "tr-adres[pandas]" # pandas eklentisiyle
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Python 3.9+ gerekir. Çalışma zamanı bağımlılığı yoktur.
|
|
73
|
+
|
|
74
|
+
### Hızlı başlangıç
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
>>> from tr_adres import parse
|
|
78
|
+
>>> a = parse("caferaga mh. moda cd. no:12/3 kadikoy")
|
|
79
|
+
>>> a.mahalle, a.cadde, a.cadde_tipi, a.bina_no, a.daire_no
|
|
80
|
+
('Caferağa', 'Moda', 'Cadde', '12', '3')
|
|
81
|
+
>>> a.ilce, a.il, a.il_plaka
|
|
82
|
+
('Kadıköy', 'İstanbul', 34)
|
|
83
|
+
>>> a.notlar
|
|
84
|
+
['il, ilçeden çıkarıldı: İstanbul']
|
|
85
|
+
>>> str(a)
|
|
86
|
+
'Caferağa Mah. Moda Cad. No:12 D:3 Kadıköy/İstanbul'
|
|
87
|
+
>>> tr_adres.format(a, style="resmi")
|
|
88
|
+
'Caferağa Mahallesi, Moda Caddesi, No: 12, İç Kapı No: 3, Kadıköy/İSTANBUL'
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Önce / sonra
|
|
93
|
+
|
|
94
|
+
| Girdi | `normalize()` çıktısı |
|
|
95
|
+
|---|---|
|
|
96
|
+
| `caferaga mh moda cd no 12 d 3 kadikoy istanbul` | `Caferağa Mah. Moda Cad. No:12 D:3 Kadıköy/İstanbul` |
|
|
97
|
+
| `ISTANBUL BESIKTAS LEVENT MAH. BUYUKDERE CAD NO 185` | `Levent Mah. Büyükdere Cad. No:185 Beşiktaş/İstanbul` |
|
|
98
|
+
| `Kızılay Mah. Atatürk Bulvarı No:115 Kat:4 Çankaya/ANKARA` | `Kızılay Mah. Atatürk Bulv. No:115 K:4 Çankaya/Ankara` |
|
|
99
|
+
| `alsancak mah 1469 sk no 8 d 2 konak izmir` | `Alsancak Mah. 1469 Sk. No:8 D:2 Konak/İzmir` |
|
|
100
|
+
| `Bağdat Caddesi No:350 Daire:12 Kat:5 Suadiye Mahallesi Kadıköy İstanbul 34740` | `Suadiye Mah. Bağdat Cad. No:350 K:5 D:12 34740 Kadıköy/İstanbul` |
|
|
101
|
+
| `Yıldız Sit. B Blk. Kat 2 D:5, Çankaya / ANKARA` | `Yıldız Sitesi B Blok K:2 D:5 Çankaya/Ankara` |
|
|
102
|
+
| `Kadikoy Caferaga Mah Moda Cad 12/3` | `Caferağa Mah. Moda Cad. No:12 D:3 Kadıköy/İstanbul` |
|
|
103
|
+
| `Levent Mah. Büyükdere Cad. No:185 Besiktas/Istnbul` | `Levent Mah. Büyükdere Cad. No:185 Beşiktaş/İstanbul` |
|
|
104
|
+
| `Afyon Merkez Dumlupınar Mah. Kurtuluş Cad. No:7` | `Dumlupınar Mah. Kurtuluş Cad. No:7 Afyonkarahisar/Afyonkarahisar` |
|
|
105
|
+
| `Mahalle: Caferağa, Cadde: Moda, No: 5, İlçe: Kadıköy, İl: İstanbul` | `Caferağa Mah. Moda Cad. No:5 Kadıköy/İstanbul` |
|
|
106
|
+
| `Bostanlı Mah. 1203/2 Sk. No:6 D:3 Karşıyaka İzmir` | `Bostanlı Mah. 1203/2 Sk. No:6 D:3 Karşıyaka/İzmir` |
|
|
107
|
+
| `Caferağa Mah. Moda Cad. No:12 Migros karşısı Kadıköy` | `Caferağa Mah. Moda Cad. No:12 Migros karşısı Kadıköy/İstanbul` |
|
|
108
|
+
| `Moda Cad. No:5 34710` | `Moda Cad. No:5 34710 Kadıköy/İstanbul` |
|
|
109
|
+
| `100. Yıl Mah. 29 Ekim Cad. No:4 Bağlar/Diyarbakır` | `100. Yıl Mah. 29 Ekim Cad. No:4 Bağlar/Diyarbakır` |
|
|
110
|
+
| `Cumhuriyet Mah. Gazi Cad. No:15-A Kat: Zemin Bayraklı İzmir` | `Cumhuriyet Mah. Gazi Cad. No:15/A K:Zemin Bayraklı/İzmir` |
|
|
111
|
+
| `Hayrullah Mah. Trabzon Cad. No:20 Onikişubat/K.Maraş` | `Hayrullah Mah. Trabzon Cad. No:20 Onikişubat/Kahramanmaraş` |
|
|
112
|
+
|
|
113
|
+
`style="resmi"` her türü açık yazar ve ili büyük harfle verir:
|
|
114
|
+
`Suadiye Mahallesi, Bağdat Caddesi, No: 350, Kat: 5, İç Kapı No: 12, 34740 Kadıköy/İSTANBUL`.
|
|
115
|
+
|
|
116
|
+
### Neleri tanır?
|
|
117
|
+
|
|
118
|
+
- **Kısaltmalar**: `mah. mh. mahallesi`, `cad. cd. caddesi`, `sok. sk. sokak sokağı`,
|
|
119
|
+
`bulv. blv. bulvarı`, `yolu`, `meydanı`, `çıkmazı`, `no: no numara #`, `d: daire iç kapı no`,
|
|
120
|
+
`k: kat`, `apt. ap. apartmanı`, `sit. sitesi konutları evleri rezidans`, `plaza`,
|
|
121
|
+
`iş merkezi`, `iş hanı`, `blk. bl. blok`, `köyü`, `pk posta kodu`; tek harflik yazım hatası
|
|
122
|
+
(`Mahalesi`, `Cadesi`) da kabul edilir.
|
|
123
|
+
- **Numaralar**: `No:12/3` (bina 12, daire 3), `No:15/A`, `No:15A`, `No:15-A`, `3. Kat`,
|
|
124
|
+
`Zemin Kat`, `Kat:-1`, `B2 Blok`, `Blok: A-1`, anahtar sözcüksüz `Moda Cad. 12/3`.
|
|
125
|
+
- **Sıra ve ayraçlar**: bileşenler herhangi bir sırada, virgüllü/virgülsüz, `/ - ; |` ya da
|
|
126
|
+
satır sonlarıyla ayrılmış olabilir. `İstanbul Kadıköy Caferağa Mah.` gibi bitişik yazılan il
|
|
127
|
+
ve ilçe mahalle adından ayrılır.
|
|
128
|
+
- **Türkçe büyük/küçük harf**: `İ/i` ve `I/ı` doğru dönüştürülür (`tr_lower`, `tr_upper`,
|
|
129
|
+
`tr_title`). Tamamen ASCII yazılmış girdide (`Kadikoy`, `BUYUKDERE`) il/ilçe adları ve sık
|
|
130
|
+
kullanılan sözcükler Türkçe yazımlarına geri döndürülür.
|
|
131
|
+
- **Yazım hataları**: il ve ilçe adları küçük bir düzenleme uzaklığıyla (Damerau-Levenshtein,
|
|
132
|
+
4–7 harfte 1, 8+ harfte 2) eşleştirilir: `Istnbul`, `Besiktas`, `Cankya`, `Ankra`, `Diyarbakr`.
|
|
133
|
+
- **Tutarlılık**: il ile ilçe her zaman birbiriyle uyumludur (`Maltepe Çankaya/Ankara` →
|
|
134
|
+
Maltepe İstanbul'da olduğu için kalan metne bırakılır). Tek ilde bulunan ilçeden il, posta
|
|
135
|
+
kodunun ilk iki hanesinden (plaka) il çıkarılır; çok illi ilçe adları (`Yenişehir`) posta
|
|
136
|
+
koduyla netleşir. `Merkez/Kütahya` → ilçe Kütahya.
|
|
137
|
+
- **Takma adlar**: `Afyon`, `K.Maraş`, `Urfa`, `Antep`, `İçel`, `İST`, `Eyüp`, `Kazan`,
|
|
138
|
+
`Karadeniz Ereğli`…
|
|
139
|
+
|
|
140
|
+
### API
|
|
141
|
+
|
|
142
|
+
| İşlev | Açıklama |
|
|
143
|
+
|---|---|
|
|
144
|
+
| `parse(text) -> Adres` | Adresi ayrıştırır |
|
|
145
|
+
| `parse_many(iterable) -> list[Adres]` | Toplu ayrıştırma (`None`/NaN boş sonuç verir) |
|
|
146
|
+
| `normalize(text, style="kargo") -> str` | Standart tek satır |
|
|
147
|
+
| `format(adres, style="kargo"\|"resmi", include_remainder=True)` | `Adres`'i (ya da metni) biçimler |
|
|
148
|
+
| `il_bul(ad_veya_plaka)`, `ilce_bul(ad, il=None)`, `ilce_ara(ad, il=None)` | Sözlük araması |
|
|
149
|
+
| `plaka(il)`, `is_valid_ilce(il, ilce)`, `merkez_ilce(il)` | Plaka ve doğrulama |
|
|
150
|
+
| `posta_kodu_il(kod)`, `posta_kodu_ilceler(kod)` | Posta kodundan il/ilçe |
|
|
151
|
+
| `iller()`, `ilceler(il=None)`, `kaynak()` | Tüm liste ve veri kaynağı |
|
|
152
|
+
| `tr_lower`, `tr_upper`, `tr_title`, `ascii_fold`, `edit_distance` | Metin yardımcıları |
|
|
153
|
+
|
|
154
|
+
`Adres` alanları: `il, ilce, mahalle, koy, cadde, cadde_tipi (Cadde/Bulvar/Yol/Meydan),
|
|
155
|
+
sokak, sokak_tipi (Sokak/Çıkmaz), site, apartman, blok, bina_no, kat, daire_no, posta_kodu,
|
|
156
|
+
il_plaka, confidence (0–1), kalan (ayrıştırılamayan metin), notlar (düzeltme ve uyarılar),
|
|
157
|
+
girdi`; ayrıca `to_dict()`, `yol` ve `gecerli` özellikleri.
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
>>> from tr_adres import il_bul, ilce_bul, ilce_ara, plaka, is_valid_ilce, tr_upper
|
|
161
|
+
>>> il_bul("Urfa").ad, il_bul(6).ad, plaka("İzmir")
|
|
162
|
+
('Şanlıurfa', 'Ankara', 35)
|
|
163
|
+
>>> [str(i) for i in ilce_ara("Yenişehir")]
|
|
164
|
+
['Yenişehir/Bursa', 'Yenişehir/Diyarbakır', 'Yenişehir/Mersin']
|
|
165
|
+
>>> is_valid_ilce("istanbul", "KADIKOY"), is_valid_ilce("Ankara", "Kadıköy")
|
|
166
|
+
(True, False)
|
|
167
|
+
>>> tr_upper("istanbul ığdır"), "istanbul ığdır".upper()
|
|
168
|
+
('İSTANBUL IĞDIR', 'ISTANBUL IĞDIR')
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Komut satırı
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
tr-adres parse "Caferağa Mah. Moda Cad. No:12/3 Kadıköy/İstanbul" # JSON
|
|
176
|
+
tr-adres normalize "caferaga mh moda cd no 12 kadikoy" # tek satır
|
|
177
|
+
tr-adres normalize musteriler.csv --column adres -o temiz.csv # adres_normalize sütunu eklenir
|
|
178
|
+
tr-adres parse musteriler.csv --column adres -o ayrik.csv # adres_il, adres_ilce, ... sütunları
|
|
179
|
+
tr-adres normalize musteriler.csv -o temiz.csv --output-encoding utf-8-sig # Excel için BOM
|
|
180
|
+
cat adresler.txt | tr-adres normalize - # satır satır
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
CSV ayırıcısı (`,` `;` sekme `|`) otomatik algılanır; girdi kodlaması varsayılan olarak
|
|
184
|
+
`utf-8-sig`'dir. `--style resmi`, `--prefix`, `--output-column`, `--delimiter` seçenekleri
|
|
185
|
+
vardır.
|
|
186
|
+
|
|
187
|
+
### pandas
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
import pandas as pd
|
|
191
|
+
import tr_adres.pandas_ext # ya da: pandas'tan sonra `import tr_adres`
|
|
192
|
+
|
|
193
|
+
df = pd.read_csv("musteriler.csv")
|
|
194
|
+
parcalar = df["adres"].tradres.parse() # il, ilce, mahalle, ... sütunlu DataFrame
|
|
195
|
+
df["adres_temiz"] = df["adres"].tradres.normalize()
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Veri kaynağı
|
|
199
|
+
|
|
200
|
+
- **İl ve ilçe adları**: T.C. İçişleri Bakanlığı, *Mülki İdare Bölümleri Envanteri* — 81 il,
|
|
201
|
+
973 ilçe. Liste, bu envanteri kaynak gösteren Türkçe Vikipedi tablosundan
|
|
202
|
+
("Türkiye'nin ilçeleri", revizyon 37373921, erişim 2026-11-08) derlenmiştir. Zonguldak'taki
|
|
203
|
+
ilçe, makale başlığı "Karadeniz Ereğli" yerine resmî adıyla **Ereğli** olarak kaydedilmiştir
|
|
204
|
+
(eski ad takma ad olarak tanınır).
|
|
205
|
+
- **Plaka kodları**: kanunla belirlenmiş 01–81.
|
|
206
|
+
- **Posta kodları**: PTT posta kodu sorgusundan, her ilçe için en küçük–en büyük aralık.
|
|
207
|
+
İlk iki hanesi plakayla çelişen 5 kayıt (Kemalpaşa/Artvin, Baklan, Yağlıdere, Menderes,
|
|
208
|
+
Arpaçay) atılmıştır; bu ilçelerde posta kodu aralığı boştur.
|
|
209
|
+
- Veri `src/tr_adres/data/gazetteer.json` içinde (~30 KB) paketle gelir;
|
|
210
|
+
`tools/build_gazetteer.py` sabitlenmiş revizyondan yeniden üretir. Bunlar resmî idari
|
|
211
|
+
adlar ve kodlardır; kaynak gösterilmesi için `tr_adres.kaynak()` kullanılabilir.
|
|
212
|
+
|
|
213
|
+
### Doğruluk
|
|
214
|
+
|
|
215
|
+
Testlerde üç ayrı, tamamen sentetik (gerçek kişi ya da teslimat adresi içermeyen) derlem vardır;
|
|
216
|
+
her alan (il, ilçe, mahalle, cadde+tipi, sokak+tipi, site, apartman, blok, bina, kat, daire,
|
|
217
|
+
posta kodu, kalan) birebir karşılaştırılır:
|
|
218
|
+
|
|
219
|
+
| Derlem | Adres | İlk çalıştırma | Şu an |
|
|
220
|
+
|---|---|---|---|
|
|
221
|
+
| Geliştirme (`tests/corpus.py`) | 191 | 191/191 tam (bir beklenti düzeltildi) | 191/191 |
|
|
222
|
+
| Ayrılmış (`HELD_OUT`) | 40 | 40/40 tam | 40/40 |
|
|
223
|
+
| Kör (`tests/blind.py`, uygulamaya bakmadan ayrı yazıldı) | 60 | **53/60 tam, alan doğruluğu %98,9** | 60/60 |
|
|
224
|
+
|
|
225
|
+
Kör derlemdeki 7 hatadan 5'i düzeltildi, 2'si beklenti farkıydı ("Merkez" ilçesini merkez
|
|
226
|
+
ilçenin adına çevirme kuralı). İlk çalıştırma sonuçları dürüst tahmindir; derlemler
|
|
227
|
+
geliştirmede kullanıldığı için "şu an" sütunu genelleme göstermez. Gerçek veride doğruluk,
|
|
228
|
+
yazım biçimine göre daha düşük olabilir.
|
|
229
|
+
|
|
230
|
+
### Sınırlamalar
|
|
231
|
+
|
|
232
|
+
- **Mahalle doğrulanmaz.** Açık lisanslı, güncel bir mahalle listesi bulunamadığından mahalle
|
|
233
|
+
yalnızca `Mah./Mahallesi` anahtar sözcüğüyle tanınır ve bir ilçeye ait olup olmadığı
|
|
234
|
+
denetlenmez. Anahtar sözcüksüz yazılan semt/mahalle adları (`Moda`, `Ulus`) `kalan`'a düşer.
|
|
235
|
+
- **Aksan geri yükleme sınırlıdır.** ASCII girdide yalnızca il/ilçe adları ve küçük bir sık
|
|
236
|
+
sözcük listesi düzeltilir; `Kayabasi` gibi diğer adlar olduğu gibi kalır.
|
|
237
|
+
- **ASCII büyük harf**: Türkçe karakter içermeyen girdide `I` → `i` kabul edilir
|
|
238
|
+
(`BILGI` → `Bilgi`); Türkçe karakter içeren girdide `I` noktasızdır (`KIZILIRMAK` →
|
|
239
|
+
`Kızılırmak`).
|
|
240
|
+
- **Bulanık ilçe eşleşmesi** yalnızca il ya da posta koduyla doğrulanırsa kabul edilir
|
|
241
|
+
(`Göztepe`, Kırşehir'in `Boztepe` ilçesine 1 harf uzaktadır).
|
|
242
|
+
- **Posta kodu aralıkları** büyükşehirlerde örtüşür; ilçe yalnızca kod tek bir ilçenin
|
|
243
|
+
aralığına düşüyorsa çıkarılır.
|
|
244
|
+
- Mahalle adının başındaki il/ilçe adı ayrılır; ilçe başka yerde yazılmamışsa
|
|
245
|
+
`Fatih Sultan Mehmet Mah.` gibi bir ad yine doğru kalır (`Sultan`, `Paşa`, `Bey`... sonrası
|
|
246
|
+
bölünmez), ama her olası çakışma önlenemez.
|
|
247
|
+
- `confidence` sezgiseldir (bulunan bileşenler, düzeltmeler, çıkarımlar ve kalan sözcükler);
|
|
248
|
+
olasılık değildir. Saniyede yaklaşık 1000 adres işlenir (tek çekirdek).
|
|
249
|
+
- Kural tabanlıdır: posta kutusu, yurt dışı ve serbest tarif adresleri ("caminin arkası")
|
|
250
|
+
kapsam dışıdır.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## English
|
|
255
|
+
|
|
256
|
+
`tr-adres` turns free-text Turkish addresses from checkout forms, shipping labels and CRM
|
|
257
|
+
exports into structured fields and a canonical one-line form. Pure Python, no runtime
|
|
258
|
+
dependencies, ships a gazetteer of all **81 provinces (il) with plate codes and 973 districts
|
|
259
|
+
(ilçe)** with PTT postal-code ranges.
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
>>> import tr_adres
|
|
263
|
+
>>> a = tr_adres.parse("ISTANBUL BESIKTAS LEVENT MAH. BUYUKDERE CAD NO 185")
|
|
264
|
+
>>> a.il, a.ilce, a.mahalle, a.cadde, a.bina_no
|
|
265
|
+
('İstanbul', 'Beşiktaş', 'Levent', 'Büyükdere', '185')
|
|
266
|
+
>>> tr_adres.normalize("Kızılay Mah. Atatürk Bulvarı No:115 Kat:4 Çankaya/ANKARA", style="resmi")
|
|
267
|
+
'Kızılay Mahallesi, Atatürk Bulvarı, No: 115, Kat: 4, Çankaya/ANKARA'
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**What it handles**: all common abbreviations (`mah. mh. cad. cd. sok. sk. bulv. blv. no: d:
|
|
272
|
+
k: kat apt. ap. blk. sit.` …), Turkish casing (`İ/i`, `I/ı` — `tr_lower`, `tr_upper`,
|
|
273
|
+
`tr_title`), ASCII-folded input (`Kadikoy` → Kadıköy), typos in province/district names
|
|
274
|
+
(bounded Damerau-Levenshtein), arbitrary component order, missing commas, `/` separators
|
|
275
|
+
(`No:12/3` = building 12, flat 3), İzmir-style numbered streets (`1203/2 Sk.`), floors
|
|
276
|
+
(`3. Kat`, `Zemin Kat`, `Kat:-1`), blocks (`B2 Blok`), labelled forms (`İl: … İlçe: …`),
|
|
277
|
+
postal codes (province from the first two digits, district from PTT ranges when unambiguous),
|
|
278
|
+
and colloquial names (`Afyon`, `K.Maraş`, `Urfa`, `Antep`, `İçel`). Province and district are
|
|
279
|
+
always mutually consistent; a district that does not belong to the province is left in the
|
|
280
|
+
remainder. Anything not understood goes to `kalan`, and every correction or inference is
|
|
281
|
+
recorded in `notlar`.
|
|
282
|
+
|
|
283
|
+
**API** — `parse`, `parse_many`, `normalize`, `format(adres, style="kargo"|"resmi")`,
|
|
284
|
+
`il_bul`, `ilce_bul`, `ilce_ara`, `plaka`, `is_valid_ilce`, `merkez_ilce`, `posta_kodu_il`,
|
|
285
|
+
`posta_kodu_ilceler`, `iller`, `ilceler`, `kaynak`, `tr_lower`, `tr_upper`, `tr_title`,
|
|
286
|
+
`ascii_fold`, `edit_distance`. See the Turkish section above for the field list.
|
|
287
|
+
|
|
288
|
+
**CLI** — `tr-adres parse "…"` prints JSON; `tr-adres normalize file.csv --column adres -o
|
|
289
|
+
out.csv` adds an `adres_normalize` column (`tr-adres parse file.csv` adds `adres_il`,
|
|
290
|
+
`adres_ilce`, …). Delimiters are sniffed; use `--output-encoding utf-8-sig` for Excel.
|
|
291
|
+
|
|
292
|
+
**pandas** — `pip install "tr-adres[pandas]"`, then `import tr_adres.pandas_ext` (or import
|
|
293
|
+
`tr_adres` after pandas) and use `df["adres"].tradres.parse()` / `.normalize()`.
|
|
294
|
+
|
|
295
|
+
**Data** — district names from the Ministry of Interior inventory (via the Turkish Wikipedia
|
|
296
|
+
table that cites it, pinned revision 37373921), plate codes 01–81, PTT postal-code envelopes;
|
|
297
|
+
counts verified by the test suite (81 / 973, unique plates). The Zonguldak district is stored
|
|
298
|
+
under its official name *Ereğli* ("Karadeniz Ereğli" is accepted as an alias).
|
|
299
|
+
|
|
300
|
+
**Accuracy** — on a blind, synthetic 60-address set written without access to the code, the
|
|
301
|
+
first run scored 53/60 fully correct addresses and 98.9 % field accuracy; all three test
|
|
302
|
+
corpora (291 addresses) now pass. These are synthetic addresses, so expect lower accuracy on
|
|
303
|
+
real-world data.
|
|
304
|
+
|
|
305
|
+
**Limitations** — neighbourhoods (mahalle) are recognised by keyword only and are *not*
|
|
306
|
+
validated (no permissively licensed mahalle list was available); diacritics are restored for
|
|
307
|
+
province/district names and a small common-word list only; in all-ASCII input `I` is read as
|
|
308
|
+
`i`; a typo-matched district is accepted only when confirmed by the province or the postal
|
|
309
|
+
code; postal-code ranges overlap in metropolitan areas; `confidence` is a heuristic score,
|
|
310
|
+
not a probability. Throughput is about 1,000 addresses per second on one core.
|
|
311
|
+
|
|
312
|
+
## Lisans / License
|
|
313
|
+
|
|
314
|
+
MIT © Yusuf Eminoğlu. Bkz. / see [LICENSE](LICENSE) ve atıf için / and for citation
|
|
315
|
+
[CITATION.cff](CITATION.cff).
|