# Fast search by title/subtitle
./oe1archive -s "Show Name"
+# Search for show with special characters (automatically escaped)
+./oe1archive -s "Das gute Leben (2)"
+
+# Search using regex patterns (wildcards still work)
+./oe1archive -s "Das.*Leben"
+
+# Search with alternation (OR) patterns
+./oe1archive -s "Music|Talk"
+
# Deep search including descriptions
./oe1archive -s "Some Keyword" -e -r 30
# Batch download all matches (fast search)
./oe1archive -d "Show Name" -p "prefix" -r 30
+# Batch download with special characters in title
+./oe1archive -d "Das gute Leben (2)" -p "prefix"
+
# Batch download all matches (deep search)
./oe1archive -d "Some Keyword" -p "prefix" -e -r 30
```
+## Search Behavior and Regex Escaping
+
+The search feature uses **smart escaping** to make searching for titles with special characters intuitive, while preserving regex pattern support.
+
+### Automatically Escaped Characters
+The following characters are **automatically escaped** (treated as literals):
+- `(` `)` - parentheses
+- `{` `}` - curly braces
+
+This means you can search for titles like "Das gute Leben (2)" without needing to manually escape the parentheses.
+
+### Supported Regex Patterns
+The following regex patterns **still work** and are NOT escaped:
+- `.*` - match any characters (wildcard)
+- `.+` - match one or more of any character
+- `|` - alternation (OR operator)
+- `^` - start of string
+- `$` - end of string
+- `[...]` - character classes
+
+### Examples
+```bash
+# Literal search - parentheses are automatically escaped
+./oe1archive -s "Das gute Leben (2)"
+
+# Regex wildcard - matches "Das gute Leben", "Das schöne Leben", etc.
+./oe1archive -s "Das.*Leben"
+
+# Combine both - wildcard with escaped parentheses
+./oe1archive -s "Das.*Leben (2)"
+
+# Alternation - matches either "Music" or "Talk"
+./oe1archive -s "Music|Talk"
+```
+
## How It Works
The OE1 API provides a rolling weekly window of current broadcasts. Streams
akm = ""
return description + "<br>" + akm
+ def _smart_escape_for_regex(self, pattern):
+ """Escape literal chars () {} while preserving regex patterns like .*
+
+ Args:
+ pattern: Search pattern string
+
+ Returns:
+ Pattern with literal characters escaped for regex
+ """
+ chars_to_escape = ['(', ')', '{', '}']
+ result = pattern
+ for char in chars_to_escape:
+ result = result.replace(char, '\\' + char)
+ return result
+
def get_broadcasts_by_regex(self, key, deep_search=False):
- """Find broadcasts matching a regex pattern.
+ """Find broadcasts matching a search pattern (with smart escaping).
Args:
- key: Search pattern (regex)
+ key: Search pattern (literal by default, but supports regex patterns)
+ Literal characters like () and {} are automatically escaped,
+ while regex patterns like .* and | continue to work.
deep_search: If True, search in title, subtitle, and description.
If False, search only in title and subtitle (faster).
Skips placeholder entries.
"""
- rex = re.compile(key, re.IGNORECASE)
+ escaped_key = self._smart_escape_for_regex(key)
+ rex = re.compile(escaped_key, re.IGNORECASE)
res = []
total = sum(len(djson["broadcasts"]) for djson in self.json)