2012-01-04 3 views
7

हाय मैं मानक रेगेक्स लाइब्रेरी (regcomp, regexec ..) का उपयोग कर रहा हूँ। लेकिन अब मांग पर मुझे नियमित रूप से अभिव्यक्तियों के लिए अपने कोड में यूनिकोड समर्थन जोड़ना चाहिए।क्या POSIX regex.h यूनिकोड या मूल रूप से गैर-असीसी वर्ण प्रदान करता है?

क्या मानक रेगेक्स लाइब्रेरी यूनिकोड या मूल रूप से गैर-असीसी वर्ण प्रदान करती है? मैंने वेब पर शोध किया, और नहीं सोचा।

मेरी परियोजना संसाधन आलोचक है इसलिए मैं इसके लिए बड़ी पुस्तकालयों (आईसीयू और बूस्ट.रेगेक्स) का उपयोग नहीं करना चाहता हूं।

किसी भी मदद की सराहना की जाएगी ..

+1

मुझे नहीं पता कि, लेकिन योजना 9 रेगेक्स लाइब्रेरी है; एक यूनिक्स पोर्ट http://swtch.com/plan9port/unix/ पर 'libregexp9' – Dave

उत्तर

6

ऐसा लगता है कि POSIX Regex UTF-8 लोकेल के साथ ठीक से काम कर रहा है। मैंने अभी एक सरल परीक्षण लिखा है (नीचे देखें) और रेगेक्स "[[:alpha:]]" (उदाहरण के लिए) के खिलाफ एक सिरिलिक वर्णों के साथ स्ट्रिंग मिलान करने के लिए इसका इस्तेमाल किया है। और सब कुछ ठीक काम कर रहा है।

नोट: मुख्य बात आपको याद रखना चाहिए - रेगेक्स फ़ंक्शन लोकेल से संबंधित हैं। इसलिए आपको इससे पहले setlocale() पर कॉल करना होगा।

#include <sys/types.h> 
#include <string.h> 
#include <regex.h> 
#include <stdio.h> 
#include <locale.h> 

int main(int argc, char** argv) { 
    int ret; 
    regex_t reg; 
    regmatch_t matches[10]; 

    if (argc != 3) { 
    fprintf(stderr, "Usage: %s regex string\n", argv[0]); 
    return 1; 
    } 

    setlocale(LC_ALL, ""); /* Use system locale instead of default "C" */ 

    if ((ret = regcomp(&reg, argv[1], 0)) != 0) { 
    char buf[256]; 
    regerror(ret, &reg, buf, sizeof(buf)); 
    fprintf(stderr, "regcomp() error (%d): %s\n", ret, buf); 
    return 1; 
    } 

    if ((ret = regexec(&reg, argv[2], 10, matches, 0)) == 0) { 
    int i; 
    char buf[256]; 
    int size; 
    for (i = 0; i < sizeof(matches)/sizeof(regmatch_t); i++) { 
     if (matches[i].rm_so == -1) break; 
     size = matches[i].rm_eo - matches[i].rm_so; 
     if (size >= sizeof(buf)) { 
     fprintf(stderr, "match (%d-%d) is too long (%d)\n", 
       matches[i].rm_so, matches[i].rm_eo, size); 
     continue; 
     } 
     buf[size] = '\0'; 
     printf("%d: %d-%d: '%s'\n", i, matches[i].rm_so, matches[i].rm_eo, 
      strncpy(buf, argv[2] + matches[i].rm_so, size)); 

    } 
    } 

    return 0; 
} 

प्रयोग उदाहरण:

$ locale 
LANG=ru_RU.UTF-8 
LC_CTYPE="ru_RU.UTF-8" 
LC_COLLATE="ru_RU.UTF-8" 
... (skip) 
LC_ALL= 
$ ./reg '[[:alpha:]]' ' 359 фыва' 
0: 5-7: 'ф' 
$ 

मिलान परिणाम की लंबाई दो बाइट UTF-8 में सिरिलिक अक्षरों इतना लेता वजह से है।

+0

के तहत है, मुझे लगता है कि आप मुझे गलत समझते हैं। मैं ऐसा करना चाहता हूं: ./reg 'ç' 'çilek45' – iyasar

+0

तो समस्या क्या है? उपरोक्त कोड प्रिंट: 0: 0-2: 'ç'' आपके पैरामीटर के साथ। यही है, यह काम करता है। –

+0

क्षमा करें मेरी गलती यह धन्यवाद काम करता है .. – iyasar

6

असल में, POSIX regexes बारे में पता यूनिकोड नहीं कर रहे हैं। आप यूनिकोड वर्णों पर उनका उपयोग करने का प्रयास कर सकते हैं, लेकिन ग्लिफ के साथ समस्या हो सकती है जिनमें एकाधिक एन्कोडिंग और ऐसे अन्य मुद्दे हैं जो यूनिकोड जागरूक पुस्तकालय आपके लिए संभालते हैं।

मानक से, IEEE Std 1003.1-2008:

मिलान चरित्र एन्कोडिंग, चरित्र के ग्राफिक प्रतिनिधित्व पर नहीं के लिए इस्तेमाल किया बिट पैटर्न के आधार पर किया जाएगा। इसका अर्थ यह है कि यदि किसी चरित्र सेट में ग्राफ़िक प्रतीक के लिए दो या दो से अधिक एन्कोडिंग होते हैं, या यदि तारों की खोज में एक से अधिक कोडेट में एन्कोड किए गए टेक्स्ट होते हैं, तो एन्कोडेड प्रतीक के किसी अन्य प्रतिनिधित्व की खोज करने के लिए कोई प्रयास नहीं किया जाता है। यदि यह आवश्यक है, तो उपयोगकर्ता वांछित ग्राफिक प्रतीक के सभी बदलावों समकक्ष वर्ग निर्दिष्ट कर सकते हैं।

शायद libpcre आपके लिए काम करेगा? यह पॉज़िक्स रेगेक्स से थोड़ा भारी है, लेकिन मुझे लगता है कि यह आईसीयू या बूस्ट से हल्का है।

0

यदि आप वास्तव में "मानक" का अर्थ है, यानी std::regex सी ++ 11 से, तो आपको केवल std::wregex (और std::wstring) पर स्विच करना होगा।

+0

के साथ कोई प्रभाव नहीं पड़ता है वे POSIX मानक द्वारा निर्दिष्ट regex.h सिस्टम इंटरफ़ेस के बारे में बात कर रहे हैं – Spookbuster

संबंधित मुद्दे