---
name: extract_domains
kind: function
lang: py
domain: cybersecurity
version: "1.0.0"
purity: pure
signature: "def extract_domains(text: str) -> list[dict]"
description: "Extrae FQDNs (dominios con TLD valido) de un texto, con offsets start/end. Usa lista estatica de TLDs comunes (gTLD + ccTLD frecuentes). No valida DNS."
tags: [ioc, domain, fqdn, regex, extract, cybersecurity, python]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [re]
params:
  - name: text
    desc: "string de texto del que extraer dominios"
output: "lista de dicts con {value, start, end, type='domain'} por cada FQDN reconocido"
tested: true
tests:
  - "Dominios con TLD valido se extraen"
  - "TLD desconocido se descarta"
  - "Subdominios profundos"
test_file_path: "python/functions/cybersecurity/tests/test_extract_iocs.py"
file_path: "python/functions/cybersecurity/extract_domains.py"
---

## Ejemplo

```python
extract_domains("visit example.com or sub.test.io for info")
# [{"value": "example.com", "start": 6, "end": 17, "type": "domain"},
#  {"value": "sub.test.io", "start": 21, "end": 32, "type": "domain"}]
```

## Notas

Lista de TLDs estatica (no IANA completa). Cubre los gTLD originales, los nuevos populares (app, dev, io, ai, cloud, xyz, ...) y ccTLDs frecuentes. Si necesitas un TLD nuevo, ampliar `_VALID_TLDS` en el .py. No usa publicsuffix (dependencia externa). Si el dominio aparece dentro de un email, se extrae igual — el pipeline `extract_iocs` deduplica por offsets.
