regexescapingaugeas

Augeas: How to match dash?


Want to write a lens for duply-exclude Files. Example:

+ /etc
- /

So my lens looks like this:

module DuplyExclude =
  let nl = del /[\n]+/ "\n"
  let entry = [ label "entry" . [ label "op" . store /(\+|-)/ ] . del /[ \t]+/ " " . [ label "path" . store /\/[^ \t\n\r]+/ ] ]
  let lns = ( entry . nl )*

  test lns get "+ /hello\n+ /etc\n- /" = ?

This results in an error. I know from experimenting a bit, that the regular expression /(\+|-)/ does not match the second line. The question is: Why the dash seems to be not matchable, even if escaped by \?


Solution

  • There are two reasons for this:

    1. The test string is missing a trailing \n. This is important as lns is defined as having an entry followed by an unconditional new line. Note that this only really affects string tests with augparse because when loading files via the library, it adds a trailing \n to any file read in (since many lenses can't handle a missing EOL).
    2. The path node is defined as matching a single / followed by at least one (+) other character in store /\/[^ \t\n\r]+/. This won't match a single / entry.

    So with these two changes, this lens works:

    module DuplyExclude =
      let nl = del /[\n]+/ "\n"
      let entry = [ label "entry" . [ label "op" . store /(\+|-)/ ] . del /[ \t]+/ " " . [ label "path" . store /\/[^ \t\n\r]*/ ] ]
      let lns = ( entry . nl )*
    
      test lns get "+ /hello\n+ /etc\n- /\n" = ?
    
    Test result: /tmp/duplyexclude.aug:6.2-.44:
      { "entry"
        { "op" = "+" }
        { "path" = "/hello" }
      }
      { "entry"
        { "op" = "+" }
        { "path" = "/etc" }
      }
      { "entry"
        { "op" = "-" }
        { "path" = "/" }
      }