Skip to content

Instantly share code, notes, and snippets.

@61131
Last active August 9, 2019 08:58
Show Gist options
  • Save 61131/7c567f0199f8ce01e12507250ec2905c to your computer and use it in GitHub Desktop.
Save 61131/7c567f0199f8ce01e12507250ec2905c to your computer and use it in GitHub Desktop.
Perform regular expression substitutions on a string
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>
#include <assert.h>
size_t
strlcpy(char * Destination, const char * Source, size_t Size) {
size_t uLength;
if((Source == NULL) ||
(Destination == NULL))
return 0;
if((uLength = strnlen(Source, Size)) == 0)
return 0;
assert(uLength < Size);
strncpy(Destination, Source, uLength);
if(uLength == Size)
--uLength;
Destination[uLength] = '\0';
return uLength;
}
int
strrep(char * String, size_t Length, char * Pattern, char * Replace, int Limit, int Flags) {
regex_t sReg;
regmatch_t sMatch;
char *pString;
size_t uBytes, uIndex, uLength, uMatch, uReplace;
int nCount, nResult;
if((pString = (char *) calloc(Length, sizeof(char))) == NULL)
return 0;
if((uLength = strlcpy( pString, String, Length)) == 0) {
free(pString);
return 0;
}
uReplace = strnlen(Replace, Length);
if((nResult = regcomp(&sReg, Pattern, Flags)) != 0) {
free(pString);
return nResult;
}
nResult = regexec(&sReg, pString, 1, &sMatch, 0);
for(nCount = 0, uIndex = 0;
((nResult == 0) &&
((Limit == 0) || (nCount < Limit)));
++nCount) {
assert(sMatch.rm_eo > sMatch.rm_so);
uMatch = sMatch.rm_eo - sMatch.rm_so;
uBytes = uLength - sMatch.rm_eo;
if(uMatch != uReplace) {
if(uBytes > 0)
memmove(&pString[sMatch.rm_so + uReplace], &pString[sMatch.rm_eo], uBytes + 1);
else
pString[sMatch.rm_so + uReplace] = '\0';
}
strncpy(&pString[uIndex + sMatch.rm_so], Replace, uReplace);
uIndex += sMatch.rm_eo;
nResult = regexec(&sReg, &pString[uIndex], 1, &sMatch, REG_NOTBOL);
}
regfree(&sReg);
strlcpy(String, pString, Length);
free(pString);
return nCount;
}
@61131
Copy link
Author

61131 commented Jul 25, 2019

This is a short segment of code from another project which can be used to perform string substitutions using regular expressions (similar to what is readily available in Perl). For example:

strcpy( sBuffer, "value.XXXX" );
nCount = strrep( sBuffer, sizeof( sBuffer ), "XXXX", "abc", 0, 0 ); // "value.XXXX" -> "value.abc"

Returns number of substitutions performed. Supports restriction to limited number of matches and extended regular expressions. See regex.h for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment