简体   繁体   English

从字符串中提取字符串值

[英]extract string value from a string

gcc 4.4.3 c89 gcc 4.4.3 c89

I have the following string 我有以下字符串

sip:12387654345443222118765@xxx.xxx.xxx.xxx

How can I extract just the number? 我怎样才能提取数字? I just want the number. 我只想要这个号码。

12387654345443222118765

Many thanks for any advice, 非常感谢任何建议,

There are lots of ways to do it, if the string is well-formatted you could use strchr() to search for the : and use strchr() again to search for the @ and take everything in between. 有很多方法可以做到这一点,如果字符串格式良好,你可以使用strchr()来搜索:并再次使用strchr()来搜索@并将其中的所有内容都strchr()

Here is another method that looks for a continuous sequence of digits: 这是另一种查找连续数字序列的方法:

char *start = sipStr + strcspn(sipStr, "0123456789");
int len = strspn(start, "0123456789");

char *copy = malloc(len + 1);

memcpy(copy, start, len);
copy[len] = '\0'; //add null terminator

...
//don't forget to
free(copy);

It sounds like you want it as a numeric type, which is going to be difficult (it's too large to fit in an int or a long). 听起来你想要它作为一种数字类型,这将是困难的(它太大而不适合int或long)。 In theory you could just do: 理论上你可以做到:

const char* original = "sip:12387654345443222118765@xxx.xxx.xxx.xxx";
long num = strtoul(original + 4, NULL, 10);

but it will overflow and strtoul will return -1. 但它会溢出而strtoul会返回-1。 If you want it as a string and you know it's always going to be that exact length, you can just pull out the substring with strcpy / strncpy : 如果你想要它作为一个字符串,你知道它总是那么精确的长度,你可以用strcpy / strncpy拉出子串:

const char* original = "sip:12387654345443222118765@xxx.xxx.xxx.xxx";
char num[24];
strncpy(num, original + 4, 23);
num[23] = 0;

If you don't know it's going to be 23 characters long every time, you'll need to find the @ sign in the original string first: 如果您不知道每次长度为23个字符,您需要先在原始字符串中找到@符号:

unsigned int num_length = strchr(original, '@') - (original + 4);
char* num = malloc(num_length + 1);
strncpy(num, original + 4, num_length);
num[num_length] = 0;

Use a regular expression :) 使用正则表达式:)

#include <regex.h>
regcomp() // compile your regex
regexec() // run your regex
regfree() // free your regex

:) :)

看看strtok或strtok_r函数。

Here is something that will deal with a variable width substring, which doesn't care about the starting position of the substring. 这是处理可变宽度子字符串的东西,它不关心子字符串的起始位置。 For instance, if string was iax2:xxx@xx.xx.xx.xx , it would still work. 例如,如果string是iax2:xxx@xx.xx.xx.xx ,它仍然可以工作。 It will, however return NULL if either delimiter can't be found. 但是,如果找不到任何分隔符,它将返回NULL。

It uses strchr() to find the delimiters, which lets us know where to start copying and where to stop. 它使用strchr()来查找分隔符,这让我们知道从哪里开始复制以及在哪里停止。 It returns an allocated string, the calling function must free() the returned pointer. 它返回一个已分配的字符串,调用函数必须free()返回的指针。

I'm pretty sure this is what you want? 我很确定这就是你想要的?

Note: Edited from original to be more re-usable and a bit saner. 注意:从原始编辑为更加可重复使用且有点理智。

#include <stdio.h>                                                                              
#include <string.h>
#include <stdlib.h>

char *extract_string(const char *str, const char s1, const char s2)
{
    char *ret = NULL, *pos1 = NULL, *pos2 = NULL;
    size_t len;

    if (str == NULL || s1 < 0 || s2 < 0)
        return NULL;

    pos1 = strchr(str, s1);
    pos2 = strchr(str, s2);
    if (! pos1 || ! pos2)
        return NULL;

    len = ((pos2 - str) - (pos1 - str) - 1);
    ret = (char *) malloc(len + 1);
    if (ret == NULL)
        return NULL;

    memcpy(ret, str + (pos1 - str) + 1, len);
    ret[len] = '\0';

    return ret;
}

int main(void)
{
    const char *string = "sip:12387654345443222118765@xxx.xxx.xxx.xxx";
    char *buff = NULL;

    buff = extract_string(string, ':', '@');
    if (buff == NULL)
        return 1;

    printf("The string extracted from %s is %s\n" , string, buff);

    free(buff);

    return 0;
}

You could easily modify that to not care if the second delimiter is not found and just copy everything to the right of the first. 你可以很容易地修改它,不在乎是否找不到第二个分隔符,只是将所有内容复制到第一个分隔符的右边。 That's an exercise for the reader. 这是读者的练习。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM