anchor.diff:      {ok, Regex} = re:compile(Pattern),
       {Regex, <<"Malformed recipe">>};
   regex_for(unqualified_recipe) ->
  -    Pattern = "^" ++ ?VERSIONED_RECIPE_REGEX ++ "$",
  +    Pattern = ?ANCHOR_REGEX(?VERSIONED_RECIPE_REGEX),
       {ok, Regex} = re:compile(Pattern),
       {Regex, <<"Malformed recipe">>}.
  
positive.code: %% Recipes can be cookbook-qualified; if not, the name is taken to be
  %% the cookbook, and the recipe is implicitly assumed to be "default".
  -define(COOKBOOK_PREFIX_REGEX, "(?:" ++ ?NAME_REGEX ++ "::)?").
  -define(VERSIONED_RECIPE_REGEX, ?COOKBOOK_PREFIX_REGEX ++ ?NAME_REGEX ++ ?RECIPE_VERSION_REGEX).
  
  
  -spec regex_for(regex_name()) -> {re_regex(),  re_msg()}.
  %% @doc provide compiled regex for use externally
  regex_for(recipe_name) ->
      Pattern = "^[.[:alnum:]_-]+(::[.[:alnum:]_-]+)?$",
      {ok, Regex} = re:compile(Pattern),
      {Regex, <<"Invalid recipe name. Must only contain A-Z, a-z, 0-9, _ or -">>};
  regex_for(cookbook_version) ->
      Pattern = "^[[:digit:]]+(\\.[[:digit:]]+){1,2}$",
      {ok, Regex} = re:compile(Pattern),
      {Regex, <<"Invalid cookbook version">>};
  regex_for(cookbook_name) ->
      Pattern = "^[.[:alnum:]_-]+$",
      {ok, Regex} = re:compile(Pattern),
      {Regex, <<"Malformed cookbook name. Must only contain A-Z, a-z, 0-9, _ or -">>};
  regex_for(environment_name) ->
      Pattern = "^[.[:alnum:]_-]+$",
      {ok, Regex} = re:compile(Pattern),
      {Regex, <<"Malformed environment name. Must only contain A-Z, a-z, 0-9, _ or -">>};
  regex_for(client_name) ->
      % This might be the same as nodename -- nodename seems to allow ':' as well
      Pat = <<"^[[:alnum:]_.-]+$">>,
      {ok, Regex} = re:compile(Pat),
      {Regex, <<"Malformed client name.  Must be A-Z, a-z, 0-9, _, -, or .">>};
  
  %% used in environments
  regex_for(cookbook_version_constraint) ->
      Pattern = "^(~>|=|>=?|<=?) [[:digit:]]+(\\.[[:digit:]]+){1,2}$",
      {ok, Regex} = re:compile(Pattern),
      {Regex, <<"Invalid cookbook version constraint">>};
  
  
negative.code: 
  -include_lib("chef_regex.hrl").
  
  %% Regular Expression Macros
  %% (Just to help DRY things up and make the usage patterns a little more clear)
  
  %% We commonly need to fully anchor a regex
  -define(ANCHOR_REGEX(Regex), "^" ++ Regex ++ "$").
  
  %% Versions can only take the form MAJOR.MINOR or MAJOR.MINOR.PATCH.
  %%
  %% See http://wiki.opscode.com/display/chef/Version+Constraints
  -define(VERSION_REGEX, "[[:digit:]]+(\\.[[:digit:]]+){1,2}").
  
  %% A version is always optional for recipes
  -define(RECIPE_VERSION_REGEX, "(?:@" ++ ?VERSION_REGEX ++ ")?").
  
  %% Cookbooks, Recipes, and Roles have common naming conventions.
  %% There is a concrete reference for role names at
  