一个字符串中有多个 ,取每个 的src地址

本文介绍了一种从HTML内容中提取所有图片路径的方法,并提供了两种不同的实现方式:一种返回图片路径列表,另一种则将图片路径存入Hashtable并返回。

#region 获得图片的路径并存放
       
/// <summary>
       
/// 获得图片的路径并存放
       
/// </summary>
       
/// <param name="M_Content">要检索的内容</param>
       
/// <returns>IList</returns>
        public static IList<string> GetPicPath(string M_Content)
        {
            IList
<string> im = new List<string>();//定义一个泛型字符类
            Regex reg = new Regex(@"<img.*?src=""(?<src>[^""]*)""[^>]*>", RegexOptions.IgnoreCase);
            MatchCollection mc
= reg.Matches(M_Content); //设定要查找的字符串
            foreach(Match m in mc)
            {
                im.Add(m.Groups[
"src"].Value);
            }
           
return im;
         
        }
       
/// <summary>
       
/// 获得图片的路径并存放
       
/// </summary>
       
/// <param name="M_Content">要检索的内容</param>
       
/// <returns>Hashtable</returns>
        public static Hashtable getPicPath(string M_Content)
        {
            Hashtable hs
= new Hashtable();//构造Hashtable
            Regex reg = new Regex(@"<img.*?src=""(?<src>[^""]*)""[^>]*>", RegexOptions.IgnoreCase);
            MatchCollection mc
= reg.Matches(M_Content);
           
int i = 0;
           
foreach (Match m in mc)
            {
                i
++;
                hs.Add(i, m.Groups[
"src"].Value);//添加到Hashtable
            }
           
return hs;
        }
       
#endregion

<think>我们面对的问题:在C语言中多次提字符串中的不同参数。 根据引用内容,我们可以总结出几种方法: 1. 使用sscanf(引用[1]和[2]):适用于格式固定的字符串,可以一次性提多个参数。 2. 使用字符串处理函数(如strtok)结合类型判断(引用[5]):可以提数字和运算符等不同类型的参数。 3. 自定义循环解析(引用[4]):通过遍历字符串根据字符类型(数字、字母、符号)来提参数。 用户的需求是多次提一个字符串中的不同参数,这些参数可能类型不同(数字、字符串等),位置不固定。 下面我将分别介绍这几种方法,并给出示例代码。 ### 方法1:使用sscanf多次提字符串格式固定时,我们可以多次使用sscanf或一次使用sscanf提多个参数。 但如果参数个数不确定,我们可以使用循环和指针移动来多次提。 示例:提字符串中的所有整数(引用[1]和[2]的改进) ```c #include <stdio.h> int main() { const char *str = "abc123 def 456ghi789"; int value; int count = 0; const char *ptr = str; // 指向当前扫描位置 // 循环直到字符串结束 while (*ptr != '\0') { // 尝试从当前位置读一个整数 int n; int ret = sscanf(ptr, "%*[^0-9]%d%n", &value, &n); // 如果上面没有成功,可能是因为当前位置就是数字 if (ret <= 0) { ret = sscanf(ptr, "%d%n", &value, &n); } if (ret == 1) { printf("value %d: %d\n", ++count, value); ptr += n; // 移动指针到已读位置之后 } else { // 没有匹配到数字,移动一个字符 ptr++; } } return 0; } ``` 说明: - `%*[^0-9]`:跳过非数字字符(*表示读但不保存),遇到数字则停止。 - `%d`:读一个整数。 - `%n`:记录到当前位置为止已经读的字符数量(包括跳过的部分),用于移动指针。 但是,如果参数不仅仅是整数,还有字符串等,我们可以根据具体格式调整格式字符串。 ### 方法2:使用strtok分割字符串,再对每个分割部分进行解析(引用[5]) 如果参数由特定分隔符(如空格、逗号、&等)分隔,我们可以先分割,再解析每个部分。 示例:提由空格和逗号分隔的数字和单词 ```c #include <stdio.h> #include <string.h> #include <ctype.h> int main() { char str[] = "name=John, age=30, salary=50000"; const char delimiters[] = " ,"; // 空格和逗号作为分隔符 // 第一次分割:按分隔符将整个字符串分割成多个键值对 char *token = strtok(str, delimiters); while (token != NULL) { // 每个token可能是"name=John"这样的形式 // 第二次分割:按等号分割 char *key = token; char *value = strchr(token, '='); if (value != NULL) { *value = '\0'; // 将等号处分割为两个字符串 value++; printf("Key: %s, Value: %s\n", key, value); } else { printf("Parameter: %s\n", token); } token = strtok(NULL, delimiters); } return 0; } ``` 注意:strtok会修改原始字符串,所以如果原始字符串需要保留,请先复制一份。 ### 方法3:自定义状态机解析(引用[4]和[5]) 当参数格式复杂时,我们可以通过状态机来解析,例如引用[4]中通过上升沿、下降沿来提连续数字。 示例:提字符串中的数字和非数字部分(引用[5]) ```c #include <stdio.h> #include <string.h> #include <ctype.h> int main() { char input[] = "100+200-50*2/5"; char *ptr = input; int in_number = 0; // 状态:0表示当前不在数字中,1表示在数字中 char buffer[20]; // 用于临时存储提的部分 int buf_index = 0; while (*ptr != '\0') { if (isdigit(*ptr)) { if (!in_number) { // 开始一个数字 in_number = 1; buf_index = 0; } buffer[buf_index++] = *ptr; } else { if (in_number) { // 数字结束 buffer[buf_index] = '\0'; printf("value: %s\n", buffer); in_number = 0; } // 当前字符是运算符(非数字且非空格等) if (!isspace(*ptr)) { printf("operator: %c\n", *ptr); } } ptr++; } // 处理最后一部分是数字的情况 if (in_number) { buffer[buf_index] = '\0'; printf("value: %s\n", buffer); } return 0; } ``` ### 总结 根据参数格式选择合适的方法: - 格式固定且简单:使用sscanf - 有明确分隔符:使用strtok分割 - 格式复杂:使用状态机(自定义循环解析) 注意事项: 1. 使用sscanf时,注意指针移动和格式字符串的编写。 2. 使用strtok会修改原字符串,如果需要保留原字符串,先复制一份。 3. 自定义状态机时,注意状态转换和边界条件(如字符串结束)。 §§相关问题§§ 1. 如何提字符串中的浮点数? 2. 当参数中包含特殊字符(如引号)时如何提? 3. 如何从JSON格式的字符串中提参数?</think>### C语言多次提字符串中的不同参数方法 在C语言中多次提字符串中的不同参数,主要有以下几种高效方法,结合您的引用内容进行说明: #### 1. 使用 `sscanf()` 循环提(推荐) ```c #include <stdio.h> int main() { char data[] = "id=100&name=Alice&score=95.5"; int id; char name[20]; float score; // 第一次提:ID sscanf(data, "id=%d", &id); // 第二次提:Name char *name_ptr = strstr(data, "name="); if (name_ptr) sscanf(name_ptr, "name=%19[^&]", name); // %[^&] 匹配到&为止[^1][^4] // 第三次提:Score char *score_ptr = strstr(data, "score="); if (score_ptr) sscanf(score_ptr, "score=%f", &score); printf("ID: %d\nName: %s\nScore: %.1f\n", id, name, score); return 0; } ``` **优点**: - 精确提特定参数 - 支持不同类型数据转换(int/float/string) - 可处理URL编码参数(结合`%[^&]`) #### 2. 使用 `strtok()` 分割键值对(通用方法) ```c #include <stdio.h> #include <string.h> int main() { char input[] = "user=Bob&role=admin&level=3"; const char delimiters[] = "=&"; char *token = strtok(input, delimiters); while (token != NULL) { char *key = token; char *value = strtok(NULL, delimiters); if (value) { printf("参数: %s = %s\n", key, value); token = strtok(NULL, delimiters); // 移动到下一组 } else { break; } } return 0; } ``` **输出**: ``` 参数: user = Bob 参数: role = admin 参数: level = 3 ``` **特点**: - 自动分割所有参数键值对 - 可处理任意数量参数[^3] - 会修改原始字符串(需复制保留原串) #### 3. 状态机解析法(处理复杂格式) ```c #include <stdio.h> #include <ctype.h> void extract_params(const char *str) { enum { KEY, VALUE } state = KEY; char key[32], value[32]; int ki = 0, vi = 0; for (int i = 0; str[i]; i++) { if (str[i] == '=') { key[ki] = '\0'; state = VALUE; vi = 0; } else if (str[i] == '&') { value[vi] = '\0'; printf("%s: %s\n", key, value); state = KEY; ki = 0; } else if (state == KEY) { key[ki++] = str[i]; } else if (state == VALUE) { value[vi++] = str[i]; } } // 处理最后一个参数 if (vi > 0) { value[vi] = '\0'; printf("%s: %s\n", key, value); } } int main() { char data[] = "product=Laptop&price=1200&stock=15"; extract_params(data); return 0; } ``` **优势**: - 不修改原始字符串 - 可处理嵌套参数 - 支持自定义分隔符[^4] #### 4. 组合方法(提数字参数) ```c #include <stdio.h> #include <string.h> int main() { char data[] = "width=1920&height=1080&fps=60"; int params[3]; char *keys[] = {"width", "height", "fps"}; for (int i = 0; i < 3; i++) { char pattern[20]; sprintf(pattern, "%s=%%d", keys[i]); // 生成匹配模式 char *pos = strstr(data, keys[i]); if (pos) sscanf(pos, pattern, &params[i]); } printf("分辨率: %dx%d@%dFPS\n", params[0], params[1], params[2]); return 0; } ``` ### 关键技巧总结 1. **指针定位**:使用 `strstr()` 快速定位参数位置[^1] 2. **安全缓冲区**:始终限制读长度(如 `%19s` 防止溢出) 3. **类型转换**: - 整数:`%d` / `%ld` - 浮点数:`%f` / `%lf` - 字符串:`%s` 或 `%[^&]`(限定符) 4. **错误处理**: ```c if (sscanf(ptr, "value=%d", &num) != 1) { printf("参数解析错误\n"); } ``` 5. **URL解码**:处理 `%20` 等编码 ```c void url_decode(char *str) { char *src = str, *dst = str; while (*src) { if (*src == '%' && isxdigit(src[1]) && isxdigit(src[2])) { *dst++ = (hex_char(src[1]) << 4) | hex_char(src[2]); src += 3; } else { *dst++ = *src++; } } *dst = '\0'; } ``` ### 性能对比 | 方法 | 优点 | 缺点 | |---------------|---------------------------|--------------------------| | `sscanf()` | 类型自动转换,代码简洁 | 无法处理嵌套结构 | | `strtok()` | 适合键值对分割 | 会修改原始字符串 | | 状态机 | 灵活处理复杂格式 | 实现较复杂 | | 组合定位 | 精确提特定参数 | 需要提前知道参数名 | > **最佳实践**:对格式规范的参数使用 `strtok()`,对特殊格式参数使用状态机解析,对需要类型转换的数字参数使用 `sscanf()`[^2][^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值