1

こんにちは。PCRE_CASELESS、PCRE_UTF8、PCRE_UCP を使用して、WINDOWS Visual Studio 8.0 および 9.0 で最新の C/C++ バージョンの PCRE を使用しています。PCRE 正規表現 [\x{00E4}]{1} を使用すると、標準ラテン コード ポイント U+00E4 を、44 41 53 20 74 61 75 73 としても知られる文字列 DAS tausendschöne Jungfräine と一致させることができます。 65 6E 64 73 63 68 C3 B6 6E 65 20 4A 75 6E 67 66 72 C3 A4 75 6C 65 69 6E. ここで、コードポイント U+00E4 (つまり、C3 B6) と U+00F6 (つまり、C3 A4) の両方を一致させて、単純なプロトタイプ C/C++ 検索および置換操作 $1 $2 を実装できるようにします。これは可能ですか?ありがとうございました。

[\x{00F6}\x{00E4}]{1,}現在、次の C++ 関数でPCRE 正規表現を使用しています。

void cInternational::RegExSearchReplace(cOrderedList *RegExList_,char **Input_) {
    const char *replacement;
    char substitution[dMaxRegExSubstitution];
    int subString;
    cPCRE *regEx;
    unsigned char* Buffer;

    Buffer = new unsigned char[1024];
    if (*Input_[0]!='\x0' && RegExList_->ResetIterator()) {
        do {
            regEx=new cPCRE();
            regEx->SetOptions(PCRE_CASELESS);
            if (regEx->Compile(RegExList_->GetCharacterField(1))) {
                // Search for Search RegEx:
                while (regEx->Execute((char *)Buffer)>0) {

                   // Found it, get Replacement expression:
                   replacement=RegExList_->GetCharacterField(2);
                    int subLen=0;
// Build substitution string by finding each $# in replacement and replacing
//   them with the appropriate found substring. Other characters in replacment
//   are sent through, untouched.
    for (int i=0;replacement[i]!='\x0';i++) {
if (replacement[i]=='$' && isdigit(replacement[i+1])) {
      subString=atoi(replacement+i+1);
      if (regEx->HasSubString(subString)) {
strncpy(substitution+subLen,
       *Input_+regEx->GetMatchStart(),
        regEx->GetMatchEnd() - regEx->GetMatchStart());

        subLen+=(regEx->GetMatchEnd() - regEx->GetMatchStart()
     }
     i++
  } else {
     substitution[subLen++]=replacement[i];
  }
}
substitution[subLen]='\x0';

// Adjust the size of Input_ accordingly:
int sizeDiff=strlen(substitution)-(regEx->GetMatchEnd()-regEx->GetMatchStart());
if (sizeDiff>0) {
    char *newInput=new char[strlen(*Input_)+sizeDiff+1];
    strcpy(newInput,*Input_);
    delete[] *Input_;
    *Input_=newInput;
}

memmove(*Input_ + regEx->GetMatchStart() + 1,
        *Input_+regEx->GetMatchEnd() + 1,
        regEx->GetMatchEnd()- regEx->GetMatchStart());
strncpy(*Input_,substitution,strlen(substitution));
(*Input_)[strlen(substitution)] = '\x0';
Buffer = Buffer + regEx->GetMatchEnd();
}
}
delete regEx;
} while (RegExList_->Next());
}
}
4

3 に答える 3

2

PCREを使用して、文字列のどこかに表示される正規表現と一致させるために使用する正規表現は次のとおりです。\x{00E4}.*\x{00F6}

説明:

\x{00E4}検索する最初のUnicode文字に一致します。

.任意の文字に一致します。

*前の期間を0回以上一致するように変更します。これにより、2番目のUnicode文字を任意の数の文字から離すことができます。

\x{00F6}検索する2番目のUnicode文字に一致します。

それらが表示された場合、これは一致します。他のことをする必要がある場合など、どのように機能するかを教えてください(たとえば、これは検索と置換の操作にはそれほど有用ではないようです。これらの文字が文字列に存在するかどうかを通知するだけです。置換を行うには、正規表現を変更する必要があります。)

于 2012-06-25T20:51:15.637 に答える
1

昨夜、PCREの開発者であるPhipHazelにメールを送信しました。Hazel氏は、\x{00f6}などの順序に依存しないPCRE正規表現を実装できることを示しています。?\ x {00e4} | \x{00e4}。?\ x {00f6}

説明を以下に示します。デイモン、助けてくれてありがとう。よろしく、フランク


差出人:Philip Hazel日付:2012年6月26日火曜日午前8時55分宛先:Frank Chang Cc:pcre-dev@exim.org

2012年6月25日月曜日、フランク・チャンは次のように書いています。

こんばんは、C / C ++PCRE8.30とPCRE_UTF8を使用しています| PCRE_UCP | PCRE_COLLATE。これが順序に依存しない

正規表現:'(?=。\ x {00F6})(?=。 \ x {00E4})'使用?=またはポジティブルックアヘッドを使用して、両方のUTF-8コードポイントがいずれかの順序で一致することを確認します。

文字列DAStausendschöneJungfräuleinに対してPCRE_compile()はOKを返し、PCRE_execute()はOKを返します。16進数では、44 41 53 20 74 61 75 73 65 6E 64 73 63 68 C3 B6 6E 65 20 4A 75 6E 67 66 72 C3 A4 75 6C 65696Eです。ただし、PCRE'\x{00F6}。*\x {00E4}'正規表現を使用したときに取得するGetMatchStart()= 14およびGetMatchEnd()= 27の代わりに、GetMatchStart()は0を返し、GetMatchEnd()は0を返します。PCRE正規表現で複数のUTF-8コードポイントの順序に依存しないマッチングを実行できるかどうかをお知らせください。ありがとうございました。

基本的なpcretestプログラムで正規表現を実行しましたが、一致しています。これにより、PCRE_compile()およびPCRE_execute()での検出結果が確認されます。

正規表現は完全にアサーションで構成されているため、実際に一致する文字列は空です(pcretestが示すように)。一致の開始と終了を指定する場合は、実際に何かに一致するように正規表現を変更する必要があります。必要なのがこれらの2つのコードポイント間の文字列である場合、どちらの順序でも、次のような単純なものです。

\x{00f6}。?\ x {00e4} | \x{00e4}。?\ x {00f6}

(空白を無視して)あなたが望むことをするべきです。

この例は実際のアプリケーションを単純化したものである可能性があり、私の単純な提案はあまり拡張性がないことを理解しています。ただし、重要な点は、文字列を抽出する場合、正規表現はアサーションだけでなく、実際のマッチングを行う必要があるということです。

フィリップ

-フィリップ・ヘイゼル

于 2012-06-26T17:16:00.007 に答える
0

PCREの順序に依存しない正規表現を作成しました。

(?=.+(\x{00F6})){1}(?=.+(\x{00E4})){1}

それは正しく機能しているようです。

于 2012-06-26T13:53:17.873 に答える