Repository: ytdl-org/youtube-dl

Issue:
Some formats not filterable because of characters not specified in str_operator_rex regex
Example format:

```
youtube-dl --list-formats "https://www.youtube.com/watch?v=bxnd_gWhWB0"                       
[youtube] bxnd_gWhWB0: Downloading webpage
[youtube] bxnd_gWhWB0: Downloading video info webpage
[youtube] bxnd_gWhWB0: Extracting video information
[youtube] bxnd_gWhWB0: Downloading DASH manifest
[youtube] bxnd_gWhWB0: Downloading DASH manifest
[info] Available formats for bxnd_gWhWB0:
format code  extension  resolution note
249          webm       audio only DASH audio   52k , opus @ 50k, 8.58MiB
250          webm       audio only DASH audio   63k , opus @ 70k, 10.10MiB
171          webm       audio only DASH audio   84k , vorbis@128k (44100Hz), 13.92MiB
140          m4a        audio only DASH audio  130k , m4a_dash container, aac  @128k (44100Hz), 22.42MiB
251          webm       audio only DASH audio  133k , opus @160k, 21.92MiB
141          m4a        audio only DASH audio  256k , m4a_dash container, aac  @256k (44100Hz), 44.53MiB
278          webm       256x144    DASH video   89k , webm container, vp9, 15fps, video only, 12.55MiB
160          mp4        256x144    DASH video  115k , avc1.4d400c, 15fps, video only, 19.05MiB
242          webm       426x240    DASH video  158k , vp9, 30fps, video only, 16.48MiB
133          mp4        426x240    DASH video  250k , avc1.4d4015, 30fps, video only, 42.59MiB
243          webm       640x360    DASH video  265k , vp9, 30fps, video only, 31.04MiB
134          mp4        640x360    DASH video  365k , avc1.4d401e, 30fps, video only, 45.30MiB
244          webm       854x480    DASH video  579k , vp9, 30fps, video only, 60.18MiB
135          mp4        854x480    DASH video  896k , avc1.4d401f, 30fps, video only, 99.03MiB
13           3gp        unknown    small 
17           3gp        176x144    small ,  mp4a.40.2, mp4v.20.3
36           3gp        320x240    small ,  mp4a.40.2, mp4v.20.3
5            flv        400x240    small 
43           webm       640x360    medium ,  vorbis, vp8.0
18           mp4        640x360    medium ,  mp4a.40.2, avc1.42001E (best)
```

Say I wanted to prefer the best possible `avc` format, I'm not sure how I could. I tried: 

```
$ youtube-dl -f "bestvideo[vcodec=avc1.4d401f]+bestaudio" "https://www.youtube.com/watch?v=bxnd_gWhWB0
```

But couldn't because the dot (`.`) is not part of the regex:

```
            str_operator_rex = re.compile(r'''(?x)
                \s*(?P<key>ext|acodec|vcodec|container|protocol)
                \s*(?P<op>%s)(?P<none_inclusive>\s*\?)?
                \s*(?P<value>[a-zA-Z0-9_-]+)
                \s*$
```

Which only seems to allow alphanumeric, dash and underscore for some reason.

What I'm actually looking for is some sort of wildcard:

```
$ youtube-dl -f "bestvideo[vcodec=avc1.*]+bestaudio" "https://www.youtube.com/watch?v=bxnd_gWhWB0
```

Or, better yet, some sort of normalization, since as far as I understand it, [avc1 is h264](http://www.digitalpreservation.gov/formats/fdd/fdd000081.shtml). Can anybody tell me why normalization would be undesirable?



Discussion:

Resolving patch:
diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py
--- a/youtube_dl/YoutubeDL.py
+++ b/youtube_dl/YoutubeDL.py
@@ -906,7 +906,7 @@ def _build_format_filter(self, filter_spec):
             str_operator_rex = re.compile(r'''(?x)
                 \s*(?P<key>ext|acodec|vcodec|container|protocol)
                 \s*(?P<op>%s)(?P<none_inclusive>\s*\?)?
-                \s*(?P<value>[a-zA-Z0-9_-]+)
+                \s*(?P<value>[a-zA-Z0-9._-]+)
                 \s*$
                 ''' % '|'.join(map(re.escape, STR_OPERATORS.keys())))
             m = str_operator_rex.search(filter_spec)


Test patch:
diff --git a/test/test_YoutubeDL.py b/test/test_YoutubeDL.py
--- a/test/test_YoutubeDL.py
+++ b/test/test_YoutubeDL.py
@@ -221,6 +221,16 @@ def test_format_selection_video(self):
         downloaded = ydl.downloaded_info_dicts[0]
         self.assertEqual(downloaded['format_id'], 'dash-video-low')
 
+        formats = [
+            {'format_id': 'vid-vcodec-dot', 'ext': 'mp4', 'preference': 1, 'vcodec': 'avc1.123456', 'acodec': 'none', 'url': TEST_URL},
+        ]
+        info_dict = _make_result(formats)
+
+        ydl = YDL({'format': 'bestvideo[vcodec=avc1.123456]'})
+        ydl.process_ie_result(info_dict.copy())
+        downloaded = ydl.downloaded_info_dicts[0]
+        self.assertEqual(downloaded['format_id'], 'vid-vcodec-dot')
+
     def test_youtube_format_selection(self):
         order = [
             '38', '37', '46', '22', '45', '35', '44', '18', '34', '43', '6', '5', '36', '17', '13',