文字列からワイルドカードで文字を抽出

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
あま
記事: 43
登録日時: 9年前

文字列からワイルドカードで文字を抽出

#1

投稿記事 by あま » 9年前

mainファイル

コード:

#include <stdio.h>
#include <string.h>
#include "my_func.h"

int main()
{
	char str[3][1024] = {"<input type=\"hidden\" name=\"ses\" value=\"tq9084e\">","<input type=\"text\" name=\"sess\" value=\"test\">","<input type=\"hidden\" name=\"sess\" value=\"adkdin348bna80qajklh\">"};
	char prt[] = "<input type=\"hidden\" name=\"sess\" value=\"*\">";
	char *sess = NULL;
	int i;

	for(i=0; i<3; i++)
	{
		sess = extraction(str[i],prt);

		if(sess != NULL)
		{
			break;
		}
	}

	printf("%s",sess);
	getch();
}
my_func.h

コード:

char *extraction(char *str,char *prt)
{
	static char data[1024];
	int i,x,y,flag;

	x = 0;

	for(i=0; i<strlen(prt); i++)
	{
		if(prt[i] == '*')
		{
			x = i;
		}
	}

	if(x == 0)
	{
		return NULL;
	}

	for(i=0; i<x; i++)
	{
		if(str[i] != prt[i])
		{
			return NULL;
		}
	}

	flag = 0;
	z = 0;
	x = 0;

	for(i=0; i<strlen(str); i++)
	{
		if(str[i] == prt[x])
		{
			if(flag == 1)
			{
				break;
			}
			else
			{
				x++;
			}
		}
		else if((str[i] != prt[x]) && (flag == 0))
		{
			flag = 1;
			x++;
		}

		if(flag == 1)
		{
			data[z] = str[i];
			z++;
		}
	}

	data[z] = '\0';

	if(strlen(data) == 0)
	{
		return NULL;
	}
	else
	{
		return data;
	}
}
文字列からワイルドカードで文字列を抽出するコードを書きました。
PHPの正規表現で文字列を取得するような感じです。
現在のコードでは比較文字列を
<input type=\"hidden\" name=\"sess\" value=\"*\">
このようにしてるので配列の要素2からvalueの値を取得します。
ここまではいいのですが、これを機能拡張して、ワイルドカードをn個にしようとしてます。
【例】
<input type=\"hidden\" name=\"*\" value=\"*"\>
もちろん今のままだと要素0と要素2に該当するのであくまで例なのですが・・・

頭が混乱してしまい、うまく作れそうにありませんので助言お願いします。
また、今のコードでおかしな点、不必要な処理、間違ってる所などありましたら同時に教えてください。

あま
記事: 43
登録日時: 9年前

Re: 文字列からワイルドカードで文字を抽出

#2

投稿記事 by あま » 9年前

ごめんなさい。
ヘッダー内の
int i,x,y,flag;
これミスです。
正しくは
int i,x,z,flag;
です。

あま
記事: 43
登録日時: 9年前

Re: 文字列からワイルドカードで文字を抽出

#3

投稿記事 by あま » 9年前

結構頑張ってるんですけどまだ出来ませんww
難しいですねぇ・・・

なにか方法ないですか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 9年前
住所: 東海地方
連絡を取る:

Re: 文字列からワイルドカードで文字を抽出

#4

投稿記事 by softya(ソフト屋) » 9年前

やった事は有りませんが、最初の*までの文字列パターンを見つけたときに再帰呼び出しで残りのパターンとの頃の文字列を処理させれば良いような気がします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

あま
記事: 43
登録日時: 9年前

Re: 文字列からワイルドカードで文字を抽出

#5

投稿記事 by あま » 9年前

softya(ソフト屋) さんが書きました:やった事は有りませんが、最初の*までの文字列パターンを見つけたときに再帰呼び出しで残りのパターンとの頃の文字列を処理させれば良いような気がします。
なるほど。
再帰でちょっとやってみます。
言われてみれば出来そうな気がしてきました。
ちなみにこういう文字列系の処理というのはみなさんあまりやらないのでしょうか?

アバター
lriki
記事: 88
登録日時: 9年前

Re: 文字列からワイルドカードで文字を抽出

#6

投稿記事 by lriki » 9年前

再帰っていうヒントをいただいたのでちょっと書いてみました。
こんなに再起を使って書いたのは久しぶりかも。

複数の文字列を検索して、結果をリストでつないで返します。

コード:

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

// 見つかった文字列を格納する単方向リストの要素
struct Node
{
	char* str;
	Node* next;
};

// Node 構造体を作成してポインタを返す
//		str  : 格納する文字列の先頭アドレス
//		len  : 格納する文字数
//		node : 次のノード
Node* alloc_node( char* str, int len, Node* node )
{
	Node* new_node = (Node*)malloc( sizeof( Node ) );
	new_node->str = (char*)malloc( sizeof( char ) * ( len + 1 ) );

	memcpy( new_node->str, str, len );
	new_node->str[ len ] = '\0';

	new_node->next = node;

	return new_node;
}

// extraction で取得したリストの内容を表示する
void show_node( Node* node )
{
	printf( "%s\n", node->str );
	if ( node->next )
	{
		show_node( node->next );
	}
}

// extraction で取得したリストを解放する
void free_node( Node* node )
{
	if ( node->next )
	{
		free_node( node->next );
	}
	free( node->str );
	free( node );
}

// src_str を condition_str で検索してワイルドカードにマッチした文字列をリストで返す
Node* extraction( char* src_str, char* condition_str )
{
	/*
	main 関数から呼び出すときの引数
		src_str       : 検索対象文字列
		condition_str : 比較文字列

	再起関数として呼び出すときの引数
		src_str       : condition_str のカーソルを進めていって * が見つかった時の src_str[ s_cursor ]
						つまり、マッチする可能性のある文字列の先頭アドレス
		condition_str : ↑とおなじく * が見つかった時の、* の「次の文字」のアドレス
	*/
	
	int s_cursor = 0;
	int c_cursor = 0;
	char key_char = condition_str[ 0 ];	// 条件文字列中の * の次の文字

	// この for では src_str[ 0 ] から見て、最初の key_char までカーソルを進めている。
	// for 終了時、src_str[ s_cursor ] は condition_str[ 0 ] と同じ文字を指している。
	while ( 1 )
	{
		if ( src_str[ s_cursor ] == key_char )
		{
			break;
		}
		// 対象文字列の終端に達した場合
		if ( src_str[ s_cursor ] == '\0' )
		{
			return alloc_node( src_str, s_cursor - c_cursor, NULL );
		}
		++s_cursor;
	}

	while ( 1 )
	{
		// 対象文字列の終端に達した場合
		if ( src_str[ s_cursor ] == '\0' )
		{
			return alloc_node( src_str, s_cursor - c_cursor, NULL );
		}

		// 違う文字が見つかった場合
		if ( src_str[ s_cursor ] != condition_str[ c_cursor ] )
		{
			// 条件文字列のカーソルが * にたどり着いた場合
			if ( condition_str[ c_cursor ] == '*' )
			{
				// 失敗or終端に到達しなければ確保したポインタが帰ってくる
				Node* next_node = extraction( &src_str[ s_cursor ], &condition_str[ c_cursor + 1 ] );
				if ( next_node )
				{
					return alloc_node( src_str, s_cursor - c_cursor, next_node );
				}
			}
			// 対象文字列中の今見ている文字が * の次の文字と同じ場合
			else if ( src_str[ s_cursor ] == key_char )
			{
				// 条件文字列のカーソルをリセットして検索を再スタートさせる
				c_cursor = 0;
				continue;
			}
			// 全然違う文字の場合
			else
			{
				return 0;
			}
		}
		++s_cursor;
		++c_cursor;
	}	
}


int main()
{
    char str[ 3 ][ 1024 ] = {
    	"<input type=\"hidden\" name=\"ses\" value=\"tq9084e\">",
    	"<input type=\"text\" name=\"sess\" value=\"test\">",
    	"<input type=\"hidden\" name=\"sess\" value=\"adkdin348bna80qajklh\">" };

    char prt[] = "<input type=\"hidden\" name=\"*\" value=\"*\">";

	Node* result = extraction( str[ 2 ], prt );

	if ( result )
	{
		show_node( result->next );	// 一番先頭のノードには空の文字列が入っているのでとばす
		free_node( result );
	}
	else
	{
		printf( "一致しませんでした。\n" );
	}
}

あま
記事: 43
登録日時: 9年前

Re: 文字列からワイルドカードで文字を抽出

#7

投稿記事 by あま » 9年前

ちょっと仕事が忙しくてコードを触る時間がなかったので
随分たってしまいましたが無事に再帰使って完成しました。
ありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る