Skip to content

Instantly share code, notes, and snippets.

@doraTeX
Last active July 31, 2020 13:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save doraTeX/3163b5aef70951ac8c541c4c77ac6293 to your computer and use it in GitHub Desktop.
Save doraTeX/3163b5aef70951ac8c541c4c77ac6293 to your computer and use it in GitHub Desktop.
引数に与えられた日本語文字列を形態素解析しひらがなに変換して出力するコマンドラインユーティリティ on macOS

コンパイル法

Objective-C 版

$ clang -framework Foundation -o ToHiragana ToHiragana.m  

Swift 版

$ swiftc ToHiragana.swift

使用例

$ ./ToHiragana 吾輩は猫である。名前はまだ無い。どこで生れたかとんと見当がつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している 。吾輩はここで始めて人間というものを見た。
わがはいはねこである。なまえはまだない。どこでうまれたかとんとけんとうがつかぬ。なんでもうすぐらいじめじめしたところでにゃあにゃあないていたことだけはきおくしている。わがはいはここではじめてにんげんというものをみた。
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
if (argc <= 1) {
fputs("ERROR: no arguments\n", stderr);
return 1;
}
// コマンドライン引数で与えられた各引数をひらがなに直してスペース区切りで出力
for (int i = 1; i < argc; i++){
NSString *input = [NSString stringWithUTF8String: argv[i]]; // 第i引数文字列
CFRange range = CFRangeMake(0, [input length]);
//(現在のユーザの言語環境によらず)日本語ロカールを生成
CFLocaleIdentifier jaLocaleIdentifier = CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorDefault, CFSTR("ja"));
CFLocaleRef locale = CFLocaleCreate(kCFAllocatorDefault, jaLocaleIdentifier);
// tokenizer を生成
CFStringTokenizerRef tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, (CFStringRef)input, range, kCFStringTokenizerUnitWordBoundary, locale);
CFStringTokenizerTokenType tokenType = CFStringTokenizerGoToTokenAtIndex(tokenizer, 0); // 冒頭位置にセット
NSMutableString *result = [NSMutableString string]; // 出力された形態素のひらがなをつないで収録していく
// 形態素解析を実行
while (tokenType != kCFStringTokenizerTokenNone) {
CFTypeRef latin = CFStringTokenizerCopyCurrentTokenAttribute(tokenizer, kCFStringTokenizerAttributeLatinTranscription); // 現トークンの読みをローマ字に起こす
NSString *hiragana = [[NSString stringWithFormat:@"%@", latin] stringByApplyingTransform:NSStringTransformLatinToHiragana reverse:NO]; // ローマ字をひらがなに変換
CFRelease(latin);
[result appendString:hiragana]; // 変換結果を追加
tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer); // 次のトークンへ
}
// メモリ解放
CFRelease(tokenizer);
CFRelease(locale);
CFRelease(jaLocaleIdentifier);
fputs([result UTF8String], stdout); // 標準出力へ
putchar((i+1 < argc) ? ' ' : '\n'); // スペース区切りで出力
}
}
return 0;
}
import Foundation
func printStdErr(_ string: String) {
FileHandle.standardError.write(string.data(using: .utf8)!)
}
var argv = ProcessInfo.processInfo.arguments
argv.remove(at: 0)
guard !argv.isEmpty else {
printStdErr("ERROR: no arguments\n")
exit(1)
}
var result: [String] = []
// コマンドライン引数で与えられた各引数をひらがなに直してスペース区切りで出力
for input in argv {
let range = CFRangeMake(0, (input as NSString).length)
//(現在のユーザの言語環境によらず)日本語ロカールを生成
let jaLocaleIdentifier = CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorDefault, "ja" as CFString)
let jaLocale = CFLocaleCreate(kCFAllocatorDefault, jaLocaleIdentifier)
// tokenizer を生成
let tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, input as CFString, range, kCFStringTokenizerUnitWordBoundary, jaLocale)
// 冒頭位置にセット
var tokenType = CFStringTokenizerGoToTokenAtIndex(tokenizer, 0)
var output = ""
while tokenType != [] {
if let latin = CFStringTokenizerCopyCurrentTokenAttribute(tokenizer, kCFStringTokenizerAttributeLatinTranscription) as? String, // 現トークンの読みをローマ字に起こす
let hiragana = latin.applyingTransform(.latinToHiragana, reverse: false) { // ローマ字をひらがなに変換
output += hiragana // 変換結果を追加
} else { // 変換に失敗した場合は元文字列の該当範囲をそのまま出力
let cfRange = CFStringTokenizerGetCurrentTokenRange(tokenizer)
let nsRange = NSRange(location: cfRange.location, length: cfRange.length)
let substring = (input as NSString).substring(with: nsRange)
output += substring
}
tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer) // 次のトークンへ
}
result.append(output)
}
print(result.joined(separator: " "))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment