Skip to content

Instantly share code, notes, and snippets.

@NachoSoto
Created June 27, 2014 19:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NachoSoto/40239c26b27ee923459e to your computer and use it in GitHub Desktop.
Save NachoSoto/40239c26b27ee923459e to your computer and use it in GitHub Desktop.
//
// MSRegex.cpp
// CoreMS
//
// Created by Nacho Soto on 6/27/14.
// Copyright (c) 2014 MindSnacks. All rights reserved.
//
#include "MSRegex.h"
using namespace std;
using namespace CoreMS;
Regex::Regex(const string &pattern)
{
if (regcomp(&_regex, pattern.c_str(), REG_EXTENDED))
{
throw InvalidPatternException(pattern);
}
}
vector<string> Regex::getGroups(const string &haystack, const size_t expectedGroups) const
{
vector<string> result;
const size_t maxMatches = 1;
const size_t maxGroups = expectedGroups + 1; // first match is `haystack`.
regmatch_t groupArray[maxGroups];
unsigned int m;
const char * cursor;
const char * const source = haystack.c_str();
m = 0;
cursor = source;
for (m = 0; m < maxMatches; ++m)
{
if (regexec(&_regex, cursor, maxGroups, groupArray, 0))
{
break;
}
unsigned int g = 0;
regoff_t offset = 0;
for (g = 0; g < maxGroups; ++g)
{
if (groupArray[g].rm_so == -1)
{
break;
}
if (g == 0)
{
offset = groupArray[g].rm_eo;
}
char cursorCopy[strlen(cursor) + 1];
strcpy(cursorCopy, cursor);
cursorCopy[groupArray[g].rm_eo] = 0;
if (g > 0)
{
result.push_back(cursorCopy + groupArray[g].rm_so);
}
}
cursor += offset;
}
if (result.size() != expectedGroups)
{
throw InvalidNumberOfGroupsException(haystack);
}
return result;
}
Regex::~Regex()
{
regfree(&_regex);
}
//
// Regex.h
// CoreMS
//
// Created by Nacho Soto on 6/27/14.
// Copyright (c) 2014 MindSnacks. All rights reserved.
//
#ifndef __CoreMS__Regex__
#define __CoreMS__Regex__
#ifdef __cplusplus
#include <string>
#include <regex.h>
namespace CoreMS
{
class Regex
{
public:
/**
* @throws `InvalidPatternException`.
*/
Regex(const std::string &pattern);
~Regex();
/**
* @throws `InvalidNumberOfGroupsException`.
*/
std::vector<std::string> getGroups(const std::string &source,
const size_t expectedGroups) const;
class Exception : public std::runtime_error
{
public:
explicit Exception(const std::string &error)
: runtime_error(error) {}
};
class InvalidPatternException : public Exception
{
public:
InvalidPatternException(const std::string &pattern)
: Exception("Invalid regex: " + pattern)
{
}
};
class InvalidNumberOfGroupsException : public Exception
{
public:
InvalidNumberOfGroupsException(const std::string &query)
: Exception("Invalid query: " + query)
{
}
};
private:
regex_t _regex;
};
}
#endif
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment