fnmatch usage with complicate pattern C
Asked Answered
I

2

1

I'm only able to match simple patterns like: "[0-9]" with fnmatch("[0-9]", tocheck, 0).

If I try something more complicated with ? or . or even a combination of these how do I use fnmatch? I saw there are some flags that can do the trick, but I don't know how to use because I'm fairly new to C.

EDIT: I saw the comment asking to give more details:

#include <stdio.h>
#include <fnmatch.h>

int main(int argc, char **argv) {
    const char *patternOne = "[0-9]";
    const char *patternTwo = ".?[a-z0-9]*?*[a-z0-9]";
    int res = fnmatch(patternTwo, "0", 0);
    printf("Result: %d\n",  res);
}

If I use patternOne the result is 0 and if I change the string to match, the result change correctly. However if I use patternTwo I never get the 0 result for whatever string I pass to fnmatch. I need to match something like this in my program. It is for an university exam, so the patterns are very intricate.

Irrefrangible answered 29/5, 2018 at 19:49 Comment(11)
This is not a standard C function. RTFM for the library that contains fnmatch().Dudek
What is fnmatch?Mcripley
Please give sample input, desired output and actual output for a few cases.Palenque
For reference, this is the definition of fnmatch: pubs.opengroup.org/onlinepubs/9699919799Weightlessness
If fnmatch is supposed to match patterns in a string, should you be using ['0'-'9'] and not [0-9]? Is there a similarity with scanf's %[]specifer?Mcripley
The POSIX function fnmatch matches wildcard patterns, not regular expressions. Wildcard patterns are described in glob(7): man7.org/linux/man-pages/man7/glob.7.html .Rondelet
Please provide the complete code that fails to do what you expect. A complete example of the pattern and filename you want to match against, and the flags you have passed.Portraiture
You may interest yourself in regex.h.Iden
Updated the question, I hope it is clear what I want to do.Irrefrangible
A more direct link to the fnmatch() POSIX spec: pubs.opengroup.org/onlinepubs/9699919799/functions/fnmatch.htmlEthe
As mentioned in a couple comments here, fnmatch() doesn't match regular expressions. As a quick example, the fact that patternTwo starts with a '.' character means it won't match "0" since for fnmatch() a period matches a period (not any character like in a regex). For example, try fnmatch(patternTwo, ".x0y1", 0) will will show a match.Ethe
P
4

Treat the pattern as a shell glob pattern. Given:

const char* patternTwo = ".?[a-z0-9]*?*[a-z0-9]";

There is no way "0" will match that. An example of a string that will match it would be: ".XaX9"

. matches .
X matches ?
a matches [a-z0-9]
X matches *?*
9 matches [a-z0-9]

The reason fnmatch() is different from glob() is so that the pattern "*" (which as a normal glob would match any string) will fail to match a file named ".profile" because dot files are treated as hidden (it is function designed to perform a file name match).

Portraiture answered 31/5, 2018 at 22:51 Comment(0)
D
0
#define _GNU_SOURCE
#include <stdio.h>
#include <fnmatch.h>

int main(int argc, char **argv) {
    const char *patternOne = "[0-9]";
    const char *patternTwo = ".?[a-z0-9]*?*[a-z0-9]";
    int res = fnmatch(patternTwo, "0", FNM_EXTMATCH);
    printf("Result: %d\n",  res);
}

Set FNM_EXTMATCH flag can use like .?[a-z0-9]*?*[a-z0-9] with pattern

FNM_EXTMATCH Besides the normal patterns, also recognize the extended patterns introduced in ksh. The patterns are written in the form explained in the following table where pattern-list is a | separated list of patterns.

?(pattern-list) The pattern matches if zero or one occurrences of any of the patterns in the pattern-list allow matching the input string.

(pattern-list) The pattern matches if zero or more occurrences of any of the patterns in the pattern-list allow matching the input string.

+(pattern-list) The pattern matches if one or more occurrences of any of the patterns in the pattern-list allow matching the input string.

@(pattern-list) The pattern matches if exactly one occurrence of any of the patterns in the pattern-list allows matching the input string.

!(pattern-list) The pattern matches if the input string cannot be matched with any of the patterns in the pattern-list.

Dickey answered 18/4, 2021 at 16:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.