RegExColumns V2

Overview

This is a new Version of my RegExColumns Script using the multi line script config for the RegExColumns Definition. There is no need to edit the actual script anymore.

Installation
Open Preferences / Toolbars / Scripts, then download RegExColumns.osp (below) and drag it to the list.
RegExColumns.osp (3.11 KB)

Usage
Once the script is installed you can add your own custom columns based on regular expressions and file names. You can find some information about the command and config parameters in the about dialog of the script add-in.

There are some default example columns to illustrate how it is done. To make the columns work, add the custom columns to your view and create the following files:

1024 Size.txt
2014-07-16 Date.txt
70 Graph.txt
70 Number.txt
70 Percent.txt
70 Rating.txt
70,5 Double.txt

Feel free to use, optimize and enhance the script. Please post your changes in this thread of the Dopus Resource Centre forum.

Hi Miran,
I've just installed your script hoping to get what I need from the file name. Unfortunately I know almost nothing about regexp and really need some help here.
Following is the pattern for the music videos I keep on my computer (always in that order, if a field is unknown then I put # in its place):

performer_title_originalPerformer_event_year_city_country.extension

bonJovi_itsAlright_bonJovi_concert_2013_london_uk.mkv

How should I write regExp to get, for example an "year" field from above file name?
If I get some idea how it looks like, I belive I'll be able to construct what I need.

And I have one more question (because I think I am confusing something here):
regExp is just for searching for let's say a string. So if I get what I need (eg. bonJovi <- from above file name) will I be able to split it into "bon jovi" using regExp ?

Thanks

So, looks like I'm getting somewhere. I got:
PERFORMER
YEAR
I know how to get:
TITLE
CITY
but the script throws an error when I'm using this:

(?<=_)

Here are a few examples to add to your config:

"Year from mvid fname":     {"header":"Year",   "inputItemProperty": "name", "regexp":"([0-9]{4})"},
"Performer":                {"header":"Performer", "inputItemProperty": "name", "regexp":"^([^_]+)_(?:[^_]+)_(?:[^_]+)_(?:[^_]+)_(?:[^_]+)_(?:[^_]+)_(?:[^_.]+)\..+$"},
"Title":                    {"header":"Title", "inputItemProperty": "name", "regexp":"^(?:[^_]+)_([^_]+)_(?:[^_]+)_(?:[^_]+)_(?:[^_]+)_(?:[^_]+)_(?:[^_.]+)\..+$"},
"Country":                  {"header":"Country", "inputItemProperty": "name", "regexp":"^(?:[^_]+)_(?:[^_]+)_(?:[^_]+)_(?:[^_]+)_(?:[^_]+)_(?:[^_]+)_([^_.]+)\..+$"}

The ?: in the parens controls capturing. You'll notice how I removed the ?: from item to be captured, and placed a ?: in the items that are not to be captured.

Here are other ways to do it, capturing the Nth field using _ as the separator. There are two special cases, the first and seventh fields. I chose as the Nth field example field 5.

"Field1":                   {"header":"Field1", "inputItemProperty": "name", "regexp":"^([^_]+)_"},
"Field5":                   {"header":"Field3", "inputItemProperty": "name", "regexp":"^(?:(?:[^_]+)_){4}([^_]+)"},
"Field7":                   {"header":"Field7", "inputItemProperty": "name", "regexp":"^(?:(?:[^_]+)_){6}([^_.]+)"}

Thank you so much - you saved me a lot of work :slight_smile:

Your code would be a bit easier to read if you had an initial

var INITIAL_COLUMNS = {
  "RegExColExample - Number": {
    "header": "Number",
    "inputItemProperty": "name",
    "regexp": "^(..) Number.*$",
    "type": "number"
  },
  "RegExColExample - Double": {
    "header": "Double",
    "inputItemProperty": "name",
    "regexp": "^(....) Double.*$",
    "type": "double",
    "justify": "right"
  },
  "RegExColExample - Percent": {
    "header": "Percent",
    "inputItemProperty": "name",
    "regexp": "^(..) Percent.*$",
    "type": "percent"
  },
  "RegExColExample - Graph": {
    "header": "Graph",
    "inputItemProperty": "name",
    "regexp": "^(..) Graph.*$",
    "type": "graph"
  },
  "RegExColExample - Rating": {
    "header": "Rating",
    "inputItemProperty": "name",
    "regexp": "^(..) Rating.*$",
    "type": "star",
    "maxStars": "10",
    "maxStarValue": "100"
  },
  "RegExColExample - Size": {
    "header": "Size",
    "inputItemProperty": "name",
    "regexp": "^([0-9]*) Size.*$",
    "type": "size"
  },
  "RegExColExample - Date": {
    "header": "Date",
    "inputItemProperty": "name",
    "regexp": "^([0-9]{4}-[0-9]{2}-[0-9]{2}) Date.*$",
    "type": "date",
    "datetimeformat": "yyyy-mm-dd"
  }
};

function SaveColumns(config, data) {
  return config.RegExColumns = JSON.stringify(data, null, 2);
}

function LoadColumns(config) {
  try {
    return JSON.parse(config.RegExColumns);
  }
  catch (err) {
    Logger (LOG_ERR, "Error parsing RegExColums!");
    Logger (LOG_ERR, "  " + err);
    dialogRegExColumnsError(err);
    return {};
  }
}

block, it would mean that the initial configuration would get stored as a nicely-formatted JSON object that way - it doesn't have to stay that way, but it's easier to read IMO. And even if a user had saved it incorrectly, the rest of the code would work. With this, your OnInit() would just have

  ...
  
  // RegExColumns Examples
  SaveColumns(initData.config, INITIAL_COLUMNS);
  ConfigDescriptions("RegExColumns") = 'RegEx Columns Definition in JSON Format.';

  // Add Configuration Descriptions
  initData.config_desc = ConfigDescriptions;
  return false;
}

to save the initial config, and the try catch blocks in other methods would be shrunk to e.g.

function OnScriptConfigChange(data) {
  LogLevel = Script.config.LogLevel;  
  Logger (LOG_DEBUG, "Config Changed.");
  Logger (LOG_DEBUG, Script.config.RegExColumns);

  Script.InitColumns();
}


function OnAddColumns(data) {
  LogLevel = Script.config.LogLevel;  
  Logger(LOG_DEBUG, "Add/Update Columns");
  
  var RegExColumns = LoadColumns(Script.config);

  for(var ColumnName in RegExColumns)
  {
    var 
      columnData = RegExColumns[ColumnName],
      column = data.AddColumn();

    column.method = "OnColumn";
    column.autorefresh = false;
    column.namerefresh = true; 
    column.name = column.label = ColumnName;
    
    if (columnData.header) column.header = columnData.header;
    if (columnData.type) column.type = columnData.type;
    if (columnData.nogroup) column.nogroup = columnData.nogroup;
    if (columnData.nosort) column.nosort = columnData.nosort;
    if (columnData.justify) column.justify = columnData.justify;
    if (columnData.type === "star" && columnData.maxStars) column.maxstars = columnData.maxStars;
  }
}

Feel free to use, enhance, optimize and beautify the script and post it as a new version to this thread/forum.
I'am happy to benefit from any further development and maybe even learn something about to do things better.

Cool, I might do that this weekend - I've got a few bits of utility code that can make writing these things simpler, will try and tidy it all up so someone other than myself late at night can find it useful :slight_smile:

I've just started playing around with this script, but I'm struggling.

"Year from Filename - Year": {"header":"Year", "inputItemProperty": "name", "regexp":"^\[(\d{4})"}

I've used the code above to get the year from the filename. All files are named:

[1984] Film.mpg
[1968] Movie.avi
[2013] Opus.mp4

Unfortunately the Year column remains empty. Where am I going wrong?

Try this one.

"Year from Filename - Year": {"header":"Year", "inputItemProperty": "name", "regexp":"^\\\[(\\d{4})"}

Haven't had the time to take a closer look, but for the time being a workaround is to use some kind of "heavy escaping" :wink:

You should actually be able to use the regular expression notation instead of putting it in a string - so your column would be:

"Year from Filename - Year": { "header": "Year", "inputItemProperty": "name", "regexp": /^\[(\d{4})/ }

Inside the forward-slashes you only need to put a slash before special characters [] .+*?(){}| and forward slashes :slight_smile:

I'm at work and don't have DO here, but it should work fine with a string or a regular expression.