tags:

views:

370

answers:

2

/Users/smcho/Desktop/bracket/[10,20] directory has "abc.txt", but when I run this python code

import glob
import os.path

path1 = "/Users/smcho/Desktop/bracket/\[10,20\]"
pathName = os.path.join(path1, "*.txt")
print glob.glob(pathName)

It returns empty list.

  • Can't python's glob doesn't handle the bracket letters or others?
  • Is there any way to solve this problem?
+5  A: 

The brackets in glob are used for character classes (e.g. [a-z] will match lowercase letters). You can put each bracket in a character class to force them being matched:

path1 = "/Users/smcho/Desktop/bracket/[[]10,20[]]"

[[] is a character class containing only the character [, and []] is a character class containing only the character ] (the closing bracket can be placed in a character class by putting it in the first position).

Additionally, since brackets aren't escaped in string literals, your code will look for a backslash as well as a bracket.

interjay
@Roger: Thanks, I've fixed it.
interjay
@~unutbu: No, `[[10,20]]` will look for one of the characters in `[102,` followed by `]`. I didn't just double the brackets but created a character class: `[[]` is a character class containing only the character `[`.
interjay
@interjay: Ah yes. You are correct. Thanks for the explanation.
unutbu
+3  A: 

glob uses fnmatch under the hood. You could use it directly:

import fnmatch, os

names = os.listdir("/Users/smcho/Desktop/bracket/[10,20]")
print fnmatch.filter(names, '*.txt')

Or using (non-public) glob.glob1() (it is present at least in Python 2.3+ including Python 3):

import glob

print glob.glob1("/Users/smcho/Desktop/bracket/[10,20]", '*.txt')

Here's the implementation of glob.glob1:

def glob1(dirname, pattern):
    if not dirname:
        dirname = os.curdir
    if isinstance(pattern, unicode) and not isinstance(dirname, unicode):
        dirname = unicode(dirname, sys.getfilesystemencoding() or
                                   sys.getdefaultencoding())
    try:
        names = os.listdir(dirname)
    except os.error:
        return []
    if pattern[0] != '.':
        names = filter(lambda x: x[0] != '.', names)
    return fnmatch.filter(names, pattern)
J.F. Sebastian