callsign-regex


Namecallsign-regex JSON
Version 0.7.1 PyPI version JSON
download
home_pagehttps://github.com/mahtin/callsign-regex
SummaryMatch ham radio callsigns based on ITU appendix42
upload_time2024-12-20 16:40:52
maintainerNone
docs_urlNone
authorMartin J Levy
requires_python>=3.7
licenseOSI Approved :: MIT License
keywords ham radio callsign itu appendix42
VCS
bugtrack_url
requirements openpyxl
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # callsign-regex
Python code to build a current regex to match all (legal) ham radio callsigns globally.
Based on the ITU Table of International Call Sign Series (Appendix 42 to the RR).

## Install

```bash
$ pip install callsign-regex
...
$
```

## Package stats

[![Downloads](https://static.pepy.tech/badge/callsign-regex)](https://pepy.tech/project/callsign-regex)
[![Downloads](https://static.pepy.tech/badge/callsign-regex/month)](https://pepy.tech/project/callsign-regex)
[![Downloads](https://static.pepy.tech/badge/callsign-regex/week)](https://pepy.tech/project/callsign-regex)
[![Downloads](https://static.pepy.tech/badge/callsign-regex/week)](https://pepy.tech/project/callsign-regex)
[![Downloads](https://img.shields.io/pypi/pyversions/callsign-regex.svg)](https://pepy.tech/project/callsign-regex)

## Producing a regex

Use the `-R` command line argument. The resulting output is the regex to match all ham radio callsigns: This regex string can be used in many programming languages (including Python).

```bash
$ callsign-regex -R
((2[A-Z]{1,2}|[BFGIKMNRW][A-Z]{0,2}|3[A-CE-Z][A-Z]{0,1}|4[A-MO-Z][A-Z]{0,1}|[5-9OUX][A-Z][A-Z]{0,1})([0-9][0-9A-Z]{0,3}[A-Z])|([ACDLP][2-9A-Z][A-Z]{0,1}|E[2-7A-Z][A-Z]{0,1}|H[2-46-9A-Z][A-Z]{0,1}|[JTV][2-8A-Z][A-Z]{0,1}|S[2-35-9A-RT-Z][A-Z]{0,1}|Y[2-9A-Y][A-Z]{0,1}|Z[238A-Z][A-Z]{0,1})([0-9A-Z]{0,3}[A-Z]))
$
```

If you expand the regex string to make it human readable, you'll see some of the optimized matching. Note that most regex libaries will optimize this much further when compiled.

```
    (
        (
            2               [A-Z]{1,2}         |
            [BFGIKMNRW]     [A-Z]{0,2}         |
            3[A-CE-Z]       [A-Z]{0,1}         |
            4[A-MO-Z]       [A-Z]{0,1}         |
            [5-9OUX][A-Z]   [A-Z]{0,1}
        )
        (
            [0-9][0-9A-Z]{0,3}[A-Z]
        )
    |
        (
            [ACDLP]         [2-9A-Z][A-Z]{0,1} |
            E[2-7A-Z]       [A-Z]{0,1}         |
            H[2-46-9A-Z]    [A-Z]{0,1}         |
            [JTV][2-8A-Z]   [A-Z]{0,1}         |
            S[2-35-9A-RT-Z] [A-Z]{0,1}         |
            Y[2-9A-Y]       [A-Z]{0,1}         |
            Z[238A-Z]       [A-Z]{0,1}
        )
        (
            [0-9A-Z]{0,3}[A-Z]
        )
    )
```

## Usage

```bash
$ callsign-regex --help
callsign-regex [-h] [-V] [-v] [-F] [-R] [-f] [-r]

Produce a valid optimized regex from the ITU Table of International Call Sign Series (Appendix 42 to the RR). Based on https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/glad.aspx

options:
  -h, --help     show this help message and exit
  -V, --version  dump version number
  -v, --verbose  verbose output
  -F, --force    force rebuild of cached regex
  -R, --regex    dump regex (to be used in code)
  -f, --forward  dump table (showing callsign to country table)
  -r, --reverse  dump reverse table (showing country to callsign table)
$
```

## Producing tables

To show the mapping of callsign to country:

```bash
$ callsign-regex -d
2          : GB/United Kingdom of Great Britain and Northern Ireland (the)
3A         : MC/Monaco
3B         : MU/Mauritius
3C         : GQ/Equatorial Guinea
3D[A-M]    : SZ/Eswatini
3D[N-Z]    : FJ/Fiji
...
$

```

To show the mapping of country to callsign:

```bash
$ callsign-regex -r
AD/Andorra                                                             : C3
AE/United Arab Emirates (the)                                          : A6
AF/Afghanistan                                                         : T6,YA
AG/Antigua and Barbuda                                                 : V2
AL/Albania                                                             : ZA
AM/Armenia                                                             : EK
...
$
```

The same output can be produced in code:
```python
from itu_appendix42 import ItuAppendix42

ituappendix42 = ItuAppendix42()
print(ItuAppendix42.regex())
```

The resulting regex can be used via many languages to pattern match a ham radio callsign correctly.

## Example code (in Python)

```python
import sys
from itu_appendix42 import ItuAppendix42

ituappendix42 = ItuAppendix42()

for line in sys.stdin:
    line = line.rstrip()
    v = ituappendix42.fullmatch(line)
    if v:
        print('%-10s' % (line))
    else:
        print('%-10s INVALID' % (line))
```

The file `examples/python_example.py` is on github (and is based on this code).

## Example code (in C)

```c
    char *callsign_regex;
    regex_t re;
    regmatch_t rm[1];

    callsign_regex = "<<INSERT FROM ABOVE OR READ IN FROM FILE>>";

    if (regcomp(&re, callsign_regex, REG_EXTENDED) != 0) {
        // bail!
    }

    char line[1024+1];
    while ((fgets(line, 1024, stdin)) != NULL) {
    if (regexec(&re, line, N_RM, rm, 0) != 0) {
        // bail!
    }
```

The file `examples/clang-example.c` is on github and contains fully working code with full error checking ability.

## Notes on ITU callsign Appendix 42

According to the [ITU](https://en.wikipedia.org/wiki/ITU_prefix) Wikipedia page, the following is a key issue when building a regex.

> With regard to the second and/or third letters in the prefixes in the list below,
> if the country in question is allocated all callsigns with A to Z in that position,
> then that country can also use call signs with the digits 0 to 9 in that position.
> For example, the United States is assigned KA–KZ, and therefore can also use prefixes like K1 or K9.

To clarify, the US is allocated the series `KAA - KAZ` `KBA - KBZ` ... `KZA - KZZ` and in that situation the normal regex would be `K[A-Z][A-Z]`; however, this text above allows `K[A-Z]{0-2}`.

This means that when parsing the ITU information you can drop the trailing letters from the search in this situation.
So far, I've not found this exact description of this rule within an ITU document; however, it's obvious that it is correct.

## Fetch new data files from the ITU (to freshen the version kept in the code)

The official database is kept by the ITU. It is called the Table of International Call Sign Series (Appendix 42 to the RR).

Hence, based on the page
[https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/glad.aspx](https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/glad.aspx)
visit this specific page in a browser on your system
[https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/call_sign_series.aspx](https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/call_sign_series.aspx)
and download via the somewhat small `.xlsx` button. This produces a file like this in your Download directory/folder:
```
    CallSignSeriesRanges-959674f2-22a8-4eb5-aa67-9df4fd606158.xlsx
```
Your downloaded filename will be different (a different set of numbers - but the same filename format - that's fine.

This package looks for the newest file of that name pattern in your `Downloads` directory/folder, so don't worry if you have  more than one file downloaded there.
Under windows the download is placed at `C:\Users\YourUsername\Downloads\` and under Linux or MacOS it's in `~/Downloads`.

A quick run of the program will read in the downloaded file and update the caches values for the regex.


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/mahtin/callsign-regex",
    "name": "callsign-regex",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "Ham Radio, Callsign, ITU, Appendix42",
    "author": "Martin J Levy",
    "author_email": "mahtin@mahtin.com",
    "download_url": "https://files.pythonhosted.org/packages/c0/cf/ee9b6815da29f21fcab7dfc5bf26ea1e151c94c40b12ae9e6042a4869f82/callsign_regex-0.7.1.tar.gz",
    "platform": null,
    "description": "# callsign-regex\nPython code to build a current regex to match all (legal) ham radio callsigns globally.\nBased on the ITU Table of International Call Sign Series (Appendix 42 to the RR).\n\n## Install\n\n```bash\n$ pip install callsign-regex\n...\n$\n```\n\n## Package stats\n\n[![Downloads](https://static.pepy.tech/badge/callsign-regex)](https://pepy.tech/project/callsign-regex)\n[![Downloads](https://static.pepy.tech/badge/callsign-regex/month)](https://pepy.tech/project/callsign-regex)\n[![Downloads](https://static.pepy.tech/badge/callsign-regex/week)](https://pepy.tech/project/callsign-regex)\n[![Downloads](https://static.pepy.tech/badge/callsign-regex/week)](https://pepy.tech/project/callsign-regex)\n[![Downloads](https://img.shields.io/pypi/pyversions/callsign-regex.svg)](https://pepy.tech/project/callsign-regex)\n\n## Producing a regex\n\nUse the `-R` command line argument. The resulting output is the regex to match all ham radio callsigns: This regex string can be used in many programming languages (including Python).\n\n```bash\n$ callsign-regex -R\n((2[A-Z]{1,2}|[BFGIKMNRW][A-Z]{0,2}|3[A-CE-Z][A-Z]{0,1}|4[A-MO-Z][A-Z]{0,1}|[5-9OUX][A-Z][A-Z]{0,1})([0-9][0-9A-Z]{0,3}[A-Z])|([ACDLP][2-9A-Z][A-Z]{0,1}|E[2-7A-Z][A-Z]{0,1}|H[2-46-9A-Z][A-Z]{0,1}|[JTV][2-8A-Z][A-Z]{0,1}|S[2-35-9A-RT-Z][A-Z]{0,1}|Y[2-9A-Y][A-Z]{0,1}|Z[238A-Z][A-Z]{0,1})([0-9A-Z]{0,3}[A-Z]))\n$\n```\n\nIf you expand the regex string to make it human readable, you'll see some of the optimized matching. Note that most regex libaries will optimize this much further when compiled.\n\n```\n    (\n        (\n            2               [A-Z]{1,2}         |\n            [BFGIKMNRW]     [A-Z]{0,2}         |\n            3[A-CE-Z]       [A-Z]{0,1}         |\n            4[A-MO-Z]       [A-Z]{0,1}         |\n            [5-9OUX][A-Z]   [A-Z]{0,1}\n        )\n        (\n            [0-9][0-9A-Z]{0,3}[A-Z]\n        )\n    |\n        (\n            [ACDLP]         [2-9A-Z][A-Z]{0,1} |\n            E[2-7A-Z]       [A-Z]{0,1}         |\n            H[2-46-9A-Z]    [A-Z]{0,1}         |\n            [JTV][2-8A-Z]   [A-Z]{0,1}         |\n            S[2-35-9A-RT-Z] [A-Z]{0,1}         |\n            Y[2-9A-Y]       [A-Z]{0,1}         |\n            Z[238A-Z]       [A-Z]{0,1}\n        )\n        (\n            [0-9A-Z]{0,3}[A-Z]\n        )\n    )\n```\n\n## Usage\n\n```bash\n$ callsign-regex --help\ncallsign-regex [-h] [-V] [-v] [-F] [-R] [-f] [-r]\n\nProduce a valid optimized regex from the ITU Table of International Call Sign Series (Appendix 42 to the RR). Based on https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/glad.aspx\n\noptions:\n  -h, --help     show this help message and exit\n  -V, --version  dump version number\n  -v, --verbose  verbose output\n  -F, --force    force rebuild of cached regex\n  -R, --regex    dump regex (to be used in code)\n  -f, --forward  dump table (showing callsign to country table)\n  -r, --reverse  dump reverse table (showing country to callsign table)\n$\n```\n\n## Producing tables\n\nTo show the mapping of callsign to country:\n\n```bash\n$ callsign-regex -d\n2          : GB/United Kingdom of Great Britain and Northern Ireland (the)\n3A         : MC/Monaco\n3B         : MU/Mauritius\n3C         : GQ/Equatorial Guinea\n3D[A-M]    : SZ/Eswatini\n3D[N-Z]    : FJ/Fiji\n...\n$\n\n```\n\nTo show the mapping of country to callsign:\n\n```bash\n$ callsign-regex -r\nAD/Andorra                                                             : C3\nAE/United Arab Emirates (the)                                          : A6\nAF/Afghanistan                                                         : T6,YA\nAG/Antigua and Barbuda                                                 : V2\nAL/Albania                                                             : ZA\nAM/Armenia                                                             : EK\n...\n$\n```\n\nThe same output can be produced in code:\n```python\nfrom itu_appendix42 import ItuAppendix42\n\nituappendix42 = ItuAppendix42()\nprint(ItuAppendix42.regex())\n```\n\nThe resulting regex can be used via many languages to pattern match a ham radio callsign correctly.\n\n## Example code (in Python)\n\n```python\nimport sys\nfrom itu_appendix42 import ItuAppendix42\n\nituappendix42 = ItuAppendix42()\n\nfor line in sys.stdin:\n    line = line.rstrip()\n    v = ituappendix42.fullmatch(line)\n    if v:\n        print('%-10s' % (line))\n    else:\n        print('%-10s INVALID' % (line))\n```\n\nThe file `examples/python_example.py` is on github (and is based on this code).\n\n## Example code (in C)\n\n```c\n    char *callsign_regex;\n    regex_t re;\n    regmatch_t rm[1];\n\n    callsign_regex = \"<<INSERT FROM ABOVE OR READ IN FROM FILE>>\";\n\n    if (regcomp(&re, callsign_regex, REG_EXTENDED) != 0) {\n        // bail!\n    }\n\n    char line[1024+1];\n    while ((fgets(line, 1024, stdin)) != NULL) {\n    if (regexec(&re, line, N_RM, rm, 0) != 0) {\n        // bail!\n    }\n```\n\nThe file `examples/clang-example.c` is on github and contains fully working code with full error checking ability.\n\n## Notes on ITU callsign Appendix 42\n\nAccording to the [ITU](https://en.wikipedia.org/wiki/ITU_prefix) Wikipedia page, the following is a key issue when building a regex.\n\n> With regard to the second and/or third letters in the prefixes in the list below,\n> if the country in question is allocated all callsigns with A to Z in that position,\n> then that country can also use call signs with the digits 0 to 9 in that position.\n> For example, the United States is assigned KA\u2013KZ, and therefore can also use prefixes like K1 or K9.\n\nTo clarify, the US is allocated the series `KAA - KAZ` `KBA - KBZ` ... `KZA - KZZ` and in that situation the normal regex would be `K[A-Z][A-Z]`; however, this text above allows `K[A-Z]{0-2}`.\n\nThis means that when parsing the ITU information you can drop the trailing letters from the search in this situation.\nSo far, I've not found this exact description of this rule within an ITU document; however, it's obvious that it is correct.\n\n## Fetch new data files from the ITU (to freshen the version kept in the code)\n\nThe official database is kept by the ITU. It is called the Table of International Call Sign Series (Appendix 42 to the RR).\n\nHence, based on the page\n[https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/glad.aspx](https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/glad.aspx)\nvisit this specific page in a browser on your system\n[https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/call_sign_series.aspx](https://www.itu.int/en/ITU-R/terrestrial/fmd/Pages/call_sign_series.aspx)\nand download via the somewhat small `.xlsx` button. This produces a file like this in your Download directory/folder:\n```\n    CallSignSeriesRanges-959674f2-22a8-4eb5-aa67-9df4fd606158.xlsx\n```\nYour downloaded filename will be different (a different set of numbers - but the same filename format - that's fine.\n\nThis package looks for the newest file of that name pattern in your `Downloads` directory/folder, so don't worry if you have  more than one file downloaded there.\nUnder windows the download is placed at `C:\\Users\\YourUsername\\Downloads\\` and under Linux or MacOS it's in `~/Downloads`.\n\nA quick run of the program will read in the downloaded file and update the caches values for the regex.\n\n",
    "bugtrack_url": null,
    "license": "OSI Approved :: MIT License",
    "summary": "Match ham radio callsigns based on ITU appendix42",
    "version": "0.7.1",
    "project_urls": {
        "Download": "https://github.com/mahtin/callsign-regex/archive/refs/tags/0.7.1.tar.gz",
        "Homepage": "https://github.com/mahtin/callsign-regex"
    },
    "split_keywords": [
        "ham radio",
        " callsign",
        " itu",
        " appendix42"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "72c735a1246f4d82caac7db3c4228e72fe39854702ba1f240c62443f4476e0fe",
                "md5": "67a74a82da21f37bd879df4c0e29f207",
                "sha256": "38d23d58b223519c238842d8ccddb8e57bac079f9b9ff194c388ba40714a7c49"
            },
            "downloads": -1,
            "filename": "callsign_regex-0.7.1-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "67a74a82da21f37bd879df4c0e29f207",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": ">=3.7",
            "size": 37802,
            "upload_time": "2024-12-20T16:40:50",
            "upload_time_iso_8601": "2024-12-20T16:40:50.275553Z",
            "url": "https://files.pythonhosted.org/packages/72/c7/35a1246f4d82caac7db3c4228e72fe39854702ba1f240c62443f4476e0fe/callsign_regex-0.7.1-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "c0cfee9b6815da29f21fcab7dfc5bf26ea1e151c94c40b12ae9e6042a4869f82",
                "md5": "3bebfab8487204c392451cbe425403e2",
                "sha256": "032de88e2267f47be2eebb8443446f7fed57eb4023e84b5c0fb2ae12dd5b0a32"
            },
            "downloads": -1,
            "filename": "callsign_regex-0.7.1.tar.gz",
            "has_sig": false,
            "md5_digest": "3bebfab8487204c392451cbe425403e2",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 36881,
            "upload_time": "2024-12-20T16:40:52",
            "upload_time_iso_8601": "2024-12-20T16:40:52.810959Z",
            "url": "https://files.pythonhosted.org/packages/c0/cf/ee9b6815da29f21fcab7dfc5bf26ea1e151c94c40b12ae9e6042a4869f82/callsign_regex-0.7.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-12-20 16:40:52",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "mahtin",
    "github_project": "callsign-regex",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "openpyxl",
            "specs": []
        }
    ],
    "lcname": "callsign-regex"
}
        
Elapsed time: 0.41291s