删除字符串中括号之间的子字符串
Remove substring between parentheses in a string
我需要删除括号之间的每个子字符串。我找到了一些解决方案,但 none 很好。这是一个例子:
我的字符串是:text(lorem(ipsum)abcd)pieceoftext 实际输出:lorem(ipsum
然而,预期输出:text(())pieceoftext 或 textpieceoftext
这是代码。我 运行 没主意了。我想过使用 strtok()
但我有两个不同的分隔符。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
const char *s = "text(lorem(ipsum)abcd)pieceoftext";
const char *patternA = "(";
const char *patternB = ")";
char *target = NULL;
char *start, *end;
if (start = strstr( s, patternA ))
{
start += strlen( patternA);
if (end = strstr( start, patternB ) )
{
target = (char *)malloc(end - start + 1);
memcpy(target, start, end - start);
target[end - start] = '[=10=]';
}
}
if (target)
printf("Answer: %s\n", target);
return 0;
}
期待听到您解决此问题的一些想法。谢谢
我不明白你为什么不只使用 strtok
(strtok_r
)。我认为它更适合这个目的。稍微玩一下就可以了。
#include <stdio.h>
#include <string.h>
int main(void) {
char str[] = "text(lorem(ipsum)abcd)pieceoftext";
char const * delim = ")(";
char *token;
char *rest = str;
while ((token = strtok_r(rest, delim, &rest))) {
printf("token: %s\n", token);
printf("rest: %s\n", rest);
}
}
您应该研究基本的解析技术,并使用这些技术来构建一个小型程序来执行您想要的操作。
hello(world)world
一个简单的解决方案:
如果前瞻是一个开括号,停止保存。直到有一个右括号。当可能有嵌套的括号时,您只需维护一个全局变量,表示我们有多 deep(当有左括号时递增,当有右括号时递减)。当此变量为零时,您可以保存。
您可以事先使用相同的模式来检查是否有足够的右括号。
首先,只需为 target
分配足够的内存,因为您需要保存整个源字符串 s
,因为您真的不知道需要多少 space .记得为字符串结尾字符添加一个。
然后将 patternA
和 patternB
从 char *
更改为 char
,这样您就可以将它们与 s
.[=18 中的各个字符进行比较=]
然后您需要遍历源字符串,跟踪您是否在括号内。由于您需要支持嵌套括号,因此我会使用一个计数器来计算您在括号内的深度:
int main()
{
const char *s = "text(lorem(ipsum)abcd)pieceoftext";
const char patternA = '(';
const char patternB = ')';
char *target;
int targetIndex = 0;
int parenDepth = 0;
target = malloc(strlen(s) + 1);
// check for malloc() error
for (int sourceIndex = 0; sourceIndex < strlen(s); sourceIndex++) {
if (s[sourceIndex] == patternA) {
// we are going deeper into parens, add to level, then ignore the char
parenDepth++;
continue;
}
if (s[sourceIndex] == patternB) {
// we are coming out of the parens, lower our level, ignore the parens char
parenDepth--;
continue;
}
if (parenDepth == 0) {
// if depth is 0, then we are not inside parens, so copy the char to target
target[targetIndex++] = s[sourceIndex];
}
}
// add end-of-string
target[targetIndex] = '[=10=]';
printf("Answer: %s\n", target);
return 0;
}
我需要删除括号之间的每个子字符串。我找到了一些解决方案,但 none 很好。这是一个例子:
我的字符串是:text(lorem(ipsum)abcd)pieceoftext 实际输出:lorem(ipsum
然而,预期输出:text(())pieceoftext 或 textpieceoftext
这是代码。我 运行 没主意了。我想过使用 strtok()
但我有两个不同的分隔符。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
const char *s = "text(lorem(ipsum)abcd)pieceoftext";
const char *patternA = "(";
const char *patternB = ")";
char *target = NULL;
char *start, *end;
if (start = strstr( s, patternA ))
{
start += strlen( patternA);
if (end = strstr( start, patternB ) )
{
target = (char *)malloc(end - start + 1);
memcpy(target, start, end - start);
target[end - start] = '[=10=]';
}
}
if (target)
printf("Answer: %s\n", target);
return 0;
}
期待听到您解决此问题的一些想法。谢谢
我不明白你为什么不只使用 strtok
(strtok_r
)。我认为它更适合这个目的。稍微玩一下就可以了。
#include <stdio.h>
#include <string.h>
int main(void) {
char str[] = "text(lorem(ipsum)abcd)pieceoftext";
char const * delim = ")(";
char *token;
char *rest = str;
while ((token = strtok_r(rest, delim, &rest))) {
printf("token: %s\n", token);
printf("rest: %s\n", rest);
}
}
您应该研究基本的解析技术,并使用这些技术来构建一个小型程序来执行您想要的操作。
hello(world)world
一个简单的解决方案:
如果前瞻是一个开括号,停止保存。直到有一个右括号。当可能有嵌套的括号时,您只需维护一个全局变量,表示我们有多 deep(当有左括号时递增,当有右括号时递减)。当此变量为零时,您可以保存。
您可以事先使用相同的模式来检查是否有足够的右括号。
首先,只需为 target
分配足够的内存,因为您需要保存整个源字符串 s
,因为您真的不知道需要多少 space .记得为字符串结尾字符添加一个。
然后将 patternA
和 patternB
从 char *
更改为 char
,这样您就可以将它们与 s
.[=18 中的各个字符进行比较=]
然后您需要遍历源字符串,跟踪您是否在括号内。由于您需要支持嵌套括号,因此我会使用一个计数器来计算您在括号内的深度:
int main()
{
const char *s = "text(lorem(ipsum)abcd)pieceoftext";
const char patternA = '(';
const char patternB = ')';
char *target;
int targetIndex = 0;
int parenDepth = 0;
target = malloc(strlen(s) + 1);
// check for malloc() error
for (int sourceIndex = 0; sourceIndex < strlen(s); sourceIndex++) {
if (s[sourceIndex] == patternA) {
// we are going deeper into parens, add to level, then ignore the char
parenDepth++;
continue;
}
if (s[sourceIndex] == patternB) {
// we are coming out of the parens, lower our level, ignore the parens char
parenDepth--;
continue;
}
if (parenDepth == 0) {
// if depth is 0, then we are not inside parens, so copy the char to target
target[targetIndex++] = s[sourceIndex];
}
}
// add end-of-string
target[targetIndex] = '[=10=]';
printf("Answer: %s\n", target);
return 0;
}