enjoylife
enjoylife

Reputation: 3861

Learning perl, what does this line do?

my @file = grep { (/\.EW/i || /\.NS/i || /\.UD/i) }readdir(DIR);

Im trying to understand the regex as well as how grep and readdir relate to one another.

Upvotes: 1

Views: 129

Answers (4)

Axeman
Axeman

Reputation: 29854

It, rather verbosely, filters all file names in a directory based on whether there is a sequence of a period followed by either 'EW', 'NS', or 'UD' in the name of a file, without reference to case. ( /i: "ignore case" ).

It does the same thing as this:

my @files = grep { /\.(?:ew|ns|ud)/i } readdir(DIR);

However, it also would allow filenames where those sequences aren't the extensions, but the beginning of a node in the filename. These types of filenames are sometimes seen more in a *nix environment: (file.ew.action.ext). But note, I said beginning (ht to ikegami), so it matches file.nst, file.nsx, and so on. So if those are *extensions, it would be better to do the following:

/\.(?:ew|ns|ud)$/i

$ indicating the end of the string (or before record separator).

Even if you wanted to keep the full range of behavior, and wanted all the extensions starting with those sequences, it is better to make it explicit, and write the expression like: /\.(?:ew|ns|ud)\w*$/ (\w* meaning 0 or more "word characters" (letters, digits + underscore)).

Upvotes: 5

user1717259
user1717259

Reputation: 2863

readdir is returning an list of the files in DIR, where DIR is a handle to a directory.

The grep {} is applying that regexp to each value it sees, and anything matching is put in @files.

The regular expression itself is matching ".EW", ".NS" or ".US" within your filenames, in a case insensitive manner. (Quotes are mine for clarity).

Upvotes: 7

Kenosis
Kenosis

Reputation: 6204

  1. A directory was first opened and it's handle is DIR
  2. readdir generates a list of the opened directory's contents--both file and directory names
  3. grep implicitly evaluates the expression in its code block against each list item (held in Perl's default scalar $_). In this case a set of regexs case-insensitively attempt to match '.EW', '.NS' or '.UD' in each list item.
  4. If the expression in grep's code evaluates to true, i.e., a match was found, the list item is passed to the array @file

Upvotes: 2

Floris
Floris

Reputation: 46425

The regular expression explained:

/\.EW/i       the character '.' followed by the letters "EW" (case insensitive)
||            or
/\.NS/i       the character '.' followed by the letters "NS" (case insensitive)
||            or
/\.UD/i)      the character '.' followed by the letters "UD" (case insensitive)

Upvotes: 1

Related Questions