C 什么';这个正则表达式匹配URL有什么问题吗?

C 什么';这个正则表达式匹配URL有什么问题吗?,c,regex,url,cgi,C,Regex,Url,Cgi,使用C中的regex.h库设置正则表达式以匹配URL有点困难。我有一个工作的IP正则表达式,我希望将其转换为匹配一个简单字符串,如www.alphanumerictext12.com | edu | org。正则表达式定义本身的语法有问题 下面是工作的IPREGEX代码和我尝试的URL regex #define IPEXPR "([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})" #define URLEXPR "(www)

使用C中的regex.h库设置正则表达式以匹配URL有点困难。我有一个工作的IP正则表达式,我希望将其转换为匹配一个简单字符串,如
www.alphanumerictext12.com | edu | org
。正则表达式定义本身的语法有问题

下面是工作的IPREGEX代码和我尝试的URL regex

#define IPEXPR    "([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})"
#define URLEXPR "(www)\\.((?:[a-z][a-z]*[0-9]+[a-z0-9]*))\\.(com|edu|org)"

regex_t regex;

if(regcomp(&regex, IPEXPR, REG_EXTENDED) != 0)
  return 0;

if(regexec(&regex, inputURL, 0, NULL, 0) != 0)
  return 0;
尝试:

我删除了
[0-9]+
,并将
[a-z][a-z]*
替换为
[a-z]+

问题在于
(?:)
,你只需要
(www)\\([a-z][a-z]*[0-9]+[a-z0-9]*)\\。(com;edu | org)


顺便说一句,你的内心表达是:“至少一个字母字符,然后至少一个数字字符,然后是任何字母数字字符”。这是你的意思吗?如果是这样的话,您可以将其缩短一点:
[a-z]+[0-9]+[a-z0-9]*
来自:

有些人在遇到问题时会想:“我知道,我会用 正则表达式。”现在他们有了 两个问题

我的意思是:你确定正则表达式是解决问题的最好方法吗?也许你可以用更轻量级的方法来测试这个字符串是否是URL


编辑

我的计算机上的以下程序(输出重定向到
/dev/null
)打印(到
stderr

接收时间:1.730000 lw时间:0.920000 节目列表:

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <regex.h>
#include <string.h>
#include <time.h>

int goodurl_rx(const char *buf) {
  static regex_t rx;
  static int done = 0;
  int e;

  if (!done) {
    done = 1;
    if ((e = regcomp(&rx, "^www\\.[a-z][a-z0-9]*\\.(com|edu|org)$", REG_EXTENDED)) != 0) {
      printf("Error %d compiling regular expression.\n", e);
      exit(EXIT_FAILURE);
    }
  }
  return !regexec(&rx, buf, 0, NULL, 0);
}

int goodurl_lw(const char *buf) {
  if (*buf++ != 'w') return 0;
  if (*buf++ != 'w') return 0;
  if (*buf++ != 'w') return 0;
  if (*buf++ != '.') return 0;
  if (!isalpha((unsigned char)*buf++)) return 0;
  while (isalnum((unsigned char)*buf)) buf++;
  if (*buf++ != '.') return 0;
  if ((*buf == 'c') && (*(buf+1) == 'o') && (*(buf+2) == 'm') && (*(buf+3) == 0)) return 1;
  if ((*buf == 'e') && (*(buf+1) == 'd') && (*(buf+2) == 'u') && (*(buf+3) == 0)) return 1;
  if ((*buf == 'o') && (*(buf+1) == 'r') && (*(buf+2) == 'g') && (*(buf+3) == 0)) return 1;
  return 0;
}

int main(void) {
  clock_t t0, t1, t2;
  char *buf[] = {"www.alphanumerics.com", "ww2.alphanumerics.com", "www.alphanumerics.net"};
  int times;

  t0 = clock();
  times = 1000000;
  while (times--) {
    printf("    %s: %s\n", buf[0], goodurl_rx(buf[0])?"pass":"invalid");
    printf("    %s: %s\n", buf[1], goodurl_rx(buf[1])?"pass":"invalid");
    printf("    %s: %s\n", buf[2], goodurl_rx(buf[2])?"pass":"invalid");
  };
  t1 = clock();
  times = 1000000;
  while (times--) {
    printf("    %s: %s\n", buf[0], goodurl_lw(buf[0])?"pass":"invalid");
    printf("    %s: %s\n", buf[1], goodurl_lw(buf[1])?"pass":"invalid");
    printf("    %s: %s\n", buf[2], goodurl_lw(buf[2])?"pass":"invalid");
  } while (0);
  t2 = clock();

  fprintf(stderr, "rx time: %f\n", (double)(t1-t0)/CLOCKS_PER_SEC);
  fprintf(stderr, "lw time: %f\n", (double)(t2-t1)/CLOCKS_PER_SEC);
  return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int goodurl_rx(常量字符*buf){
静态正则表达式rx;
静态int done=0;
INTE;
如果(!完成){
完成=1;
如果((e=regcomp(&rx,“^www\\[a-z][a-z0-9]*\\(com | edu | org)$”,注册扩展))!=0){
printf(“编译正则表达式时出现错误%d。\n”,e);
退出(退出失败);
}
}
return!regexec(&rx,buf,0,NULL,0);
}
int goodurl_lw(常量字符*buf){
如果(*buf++!='w'),则返回0;
如果(*buf++!='w'),则返回0;
如果(*buf++!='w'),则返回0;
如果(*buf++!='),则返回0;
if(!isalpha((无符号字符)*buf++)返回0;
而(isalnum((无符号字符)*buf))buf++;
如果(*buf++!='),则返回0;
如果((*buf='c')&(*(buf+1)='o')&(*(buf+2)='m')&(*(buf+3)==0))返回1;
如果((*buf=='e')&(*(buf+1)='d')&(*(buf+2)='u')&(*(buf+3)==0))返回1;
如果((*buf='o')&(*(buf+1)='r')&(*(buf+2)='g')&(*(buf+3)==0))返回1;
返回0;
}
内部主(空){
时钟t0、t1、t2;
char*buf[]={“www.alphanumerics.com”、“ww2.alphanumerics.com”、“www.alphanumerics.net”};
整数倍;
t0=时钟();
次数=1000000次;
而(次--){
printf(“%s:%s\n”,buf[0],goodurl_rx(buf[0])?“通过”:“无效”);
printf(“%s:%s\n”,buf[1],goodurl_rx(buf[1])?“通过”:“无效”);
printf(“%s:%s\n”,buf[2],goodurl_rx(buf[2])?“通过”:“无效”);
};
t1=时钟();
次数=1000000次;
而(次--){
printf(“%s:%s\n”,buf[0],goodurl_lw(buf[0])?“通过”:“无效”);
printf(“%s:%s\n”,buf[1],goodurl_lw(buf[1])?“通过”:“无效”);
printf(“%s:%s\n”,buf[2],goodurl_lw(buf[2])?“通过”:“无效”);
}而(0);
t2=时钟();
fprintf(标准,“接收时间:%f\n”(双精度)(t1-t0)/时钟每秒);
fprintf(标准,“lw时间:%f\n”(双精度)(t2-t1)/时钟每秒);
返回0;
}

您可能应该使用标准POSIX函数(替换
inet_aton()
),并处理IPv4和IPv6地址格式。

“至少一个字母字符,然后至少一个数字字符,然后是任何字母数字字符”。这是你的意思吗?不,那是个错误。我会给你的正则表达式一个尝试和报告回来,谢谢!cb那么您可能更喜欢[a-z]+[a-z0-9]*,但请注意,域名可以以数字开头:)我希望这是不区分大小写的,那么以下是更好的吗“www\\.[a-zA-Z]+[a-zA-Z0-9]*\\(com | edu | org)“你可以这样做,但这不允许
.com
.edu
作为TLD。您可以通过在regex前面添加
(?i)
标志来启用不区分大小写的匹配:
“(?i)www\\.[a-z]+[a-z0-9]*\\(com | edu | org)”
假设您正在使用的regex库支持
(?i)
。我正在Ubuntu上使用c中的regex.h。我要做个测试。“www\\.[a-z]+[a-z0-9]*\\(com | edu | org)”工作得很愉快,现在我需要添加字符-以及“我应该将它们放在哪里?”?我试图这样添加它们:[a-z0-9-904;]但失败了。我在这里的重点是什么?谢谢大家,
-
可能被regex库视为范围指示器。改为尝试
[a-z0-9_-]
(最后,不应将其作为范围指示器)。或者,试着像这样转义
-
[a-z0-9\-]
。我不确定我是否完全理解这个用法。与我目前使用的正则表达式相比,这是一种更体面的检查IP地址有效性的方法吗?(上面定义为IPEXPR)CByes,特别是因为IPv6具有inet\u pton将处理的缩写形式。这不仅仅是0-9和。嗯,在这种情况下,我相信正则表达式是最好的答案,但我当然愿意接受有效的建议。我正在以一般形式输入用户的网址:www.alphanumerics.com。你能推荐一个更轻量级的方法吗?pmg,几乎可以肯定,这个函数是用来验证用户输入的,所以在这里,一秒钟的一小部分真的不重要。但是关于开发时间、可读性、可支持性等呢?微小的更改将要求您重写代码,最终使用自制的FSA。对于这个简单的示例,我同意正则表达式函数更容易处理。然而,有一天,当你想“接受”
co.uk
net.au
时,要使
ads*
无效,而不是
cads*
。。。;两者都不好。当这种情况发生时,解析器是最好的选择,但IMVHO是一种基于REG的解决方案 rx time: 1.730000 lw time: 0.920000
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <regex.h>
#include <string.h>
#include <time.h>

int goodurl_rx(const char *buf) {
  static regex_t rx;
  static int done = 0;
  int e;

  if (!done) {
    done = 1;
    if ((e = regcomp(&rx, "^www\\.[a-z][a-z0-9]*\\.(com|edu|org)$", REG_EXTENDED)) != 0) {
      printf("Error %d compiling regular expression.\n", e);
      exit(EXIT_FAILURE);
    }
  }
  return !regexec(&rx, buf, 0, NULL, 0);
}

int goodurl_lw(const char *buf) {
  if (*buf++ != 'w') return 0;
  if (*buf++ != 'w') return 0;
  if (*buf++ != 'w') return 0;
  if (*buf++ != '.') return 0;
  if (!isalpha((unsigned char)*buf++)) return 0;
  while (isalnum((unsigned char)*buf)) buf++;
  if (*buf++ != '.') return 0;
  if ((*buf == 'c') && (*(buf+1) == 'o') && (*(buf+2) == 'm') && (*(buf+3) == 0)) return 1;
  if ((*buf == 'e') && (*(buf+1) == 'd') && (*(buf+2) == 'u') && (*(buf+3) == 0)) return 1;
  if ((*buf == 'o') && (*(buf+1) == 'r') && (*(buf+2) == 'g') && (*(buf+3) == 0)) return 1;
  return 0;
}

int main(void) {
  clock_t t0, t1, t2;
  char *buf[] = {"www.alphanumerics.com", "ww2.alphanumerics.com", "www.alphanumerics.net"};
  int times;

  t0 = clock();
  times = 1000000;
  while (times--) {
    printf("    %s: %s\n", buf[0], goodurl_rx(buf[0])?"pass":"invalid");
    printf("    %s: %s\n", buf[1], goodurl_rx(buf[1])?"pass":"invalid");
    printf("    %s: %s\n", buf[2], goodurl_rx(buf[2])?"pass":"invalid");
  };
  t1 = clock();
  times = 1000000;
  while (times--) {
    printf("    %s: %s\n", buf[0], goodurl_lw(buf[0])?"pass":"invalid");
    printf("    %s: %s\n", buf[1], goodurl_lw(buf[1])?"pass":"invalid");
    printf("    %s: %s\n", buf[2], goodurl_lw(buf[2])?"pass":"invalid");
  } while (0);
  t2 = clock();

  fprintf(stderr, "rx time: %f\n", (double)(t1-t0)/CLOCKS_PER_SEC);
  fprintf(stderr, "lw time: %f\n", (double)(t2-t1)/CLOCKS_PER_SEC);
  return 0;
}