簡體   English   中英

POSIX regex.h是否提供unicode或基本上非ascii字符?

[英]Does POSIX regex.h provide unicode or basically non-ascii characters?

嗨,我正在使用標准正則表達式庫(regcomp,regexec ..)。 但是現在按需要我應該為我的正則表達式代碼添加unicode支持。

標准正則表達式庫是否提供unicode或基本上非ascii字符? 我在網上研究,並沒有想到。

我的項目是資源批評者因此我不想使用大型庫(ICU和Boost.Regex)。

任何幫助,將不勝感激..

看起來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中的西里爾字母需要很多。

基本上,POSIX正則表達式不支持Unicode。 您可以嘗試在Unicode字符上使用它們,但是可能存在具有多種編碼的字形以及Unicode感知庫為您處理的其他此類問題。

從標准IEEE Std 1003.1-2008

匹配應基於用於編碼字符的位模式,而不是基於字符的圖形表示。 這意味着如果字符集包含兩個或多個圖形符號的編碼,或者如果搜索的字符串包含以多個代碼集編碼的文本,則不會嘗試搜索編碼符號的任何其他表示。 如果需要,用戶可以指定包含所需圖形符號的所有變體的等價類。

也許libpcre適合你? 它比POSIX正則表達稍重,但我認為它比ICU或Boost輕。

如果你的意思是“標准”,即來自C ++ 11的std::regex ,那么你需要做的就是切換到std::wregex (當然還有std::wstring )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM