현재 문자가 글자인지 확인하는 방법


9

현재 문자가 문자 (알파벳 문자)인지 확인하는 방법 (즉, [:alpha:]정규 표현식 개념 의 구문 클래스 에 속함 ). 아래와 같은 간단한 함수를 작성하고 싶습니다.

(defun test-letter () (interactive)
(if char-after-is-a-letter
    (message "This is a letter")
    (message "This is not a letter")
    )
)

업데이트는 불행하게도 문자의 클래스의 동등성 및 구문 클래스에 대한 내 가정은 [:alpha:]잘못된 것 같다.

답변:


9

유니 코드 문자 속성 사용

이것은 분명히 작동해야합니다.

(memq (get-char-code-property (char-after) 'general-category)
      '(Ll Lu Lo Lt Lm Mn Mc Me Nl))

보너스는 또한보다 빠릅니다 looking-at.


Emacs는 유니 코드 표준으로 지정된 모든 문자 속성을 저장 합니다. 로 액세스 할 수 있습니다 get-char-code-property. 특히이 general-category속성은 문자 ( Ll소문자, Lu대문자 및 다른 문자를 묻지 않음)를 지정합니다.


고마워, 이것은 문제를 해결 ۱۲۳۴۵۶۷۸۹۰하지만 아랍어 또는 히브리어 Alef와 같은 진정한 부정이 있습니다 : א, ا.
이름

@Name 고정. 다시 시도하십시오.
Malabarba

2
다시 감사합니다. 다양한 알파벳으로 확인하고 작동합니다. 내가 찾은 유일한 예외는 중국어 en.wikipedia.org/wiki/Chinese_numerals 또는 일본어 en.wikipedia.org/wiki/Japanese_numerals 와 같은 아시아 알파벳 입니다. 예를 들어 일본어 숫자 5로 간주됩니다 . 귀하의 코드는 이것을 문자로 간주합니다. 아마도 그것은 로마 숫자와 같은 문자 일 것입니다 v. 어쩌면 일본어에 익숙한 사람이 이것을 확인할 수 있습니다.
이름

1
영어 단어 five와 같으므로 문자입니다. 단어 5 대신 숫자 5를 쓰면 5영어처럼 사용 됩니다.
Muir

8

편집 : 이 답변은 25.5에서 완벽하게 유효해야합니다 ( 버그 가 수정 된 곳). 이전 버전의 경우 다른 옵션을 사용하십시오 .


현재 문자가 문자인지, 어떤 언어로든 작동해야합니다.

 (looking-at-p "[[:alpha:]]")

많은 감사, 나는 looking-at-p당신의 해결책과 looking-at다른 대답에서 사용 된 차이점에 대해 궁금 합니다 .
이름 :

1
looking-at-p일치 데이터를 설정하지 않는 것을 제외하고 두 기능은 동일 합니다.
jch

1
@Name looking-at-p는 일치 데이터를 설정하지 않기 때문에 순수한 술어에 더 가깝습니다. 이전에 검색과 같은 작업을 수행 한 경우 match-string(및 그 많은 형제) 검색 결과를 반환합니다. 한편, 술어가 아닌 버전의 경우, match-string은 찾는 일치 결과를 리턴합니다.
Malabarba

5

나는 당신이 이것으로 벗어날 수 있다고 생각합니다.

(defun test-letter ()
  (interactive)
  (let ((char (char-after)))
    (if (and (eq (char-syntax char) ?w)
             (or (> char ?9)
                 (< char ?1)))
        (message "This is a letter")
      (message "This is not a letter"))))

최신 정보

이것은 덜 효율적이지만 원하는 것에 더 가깝습니다.

(defun test-letter ()
  (interactive)
  (if (looking-at "[a-z-A-Z]")
      (message "This is a letter")
    (message "This is not a letter")))

감사합니다. 가능한 문제 :이 함수는 숫자 (123 ...)를 문자로 간주합니다.
이름

쉽게 고칠 수 있습니다.
abo-abo

다시 한번 감사드립니다. 또 다른 오 탐지 : 이것은 ۹(즉, 인도 숫자 9) 또는 ٪문자로 간주됩니다.
이름

1
첫 번째 해결책은 그리스 문자 (예 : ζ또는 α) 로 훌륭 했지만 업데이트는 아닙니다.
이름

그러나 두 가지를 결합하는 것이 더 가까운 솔루션입니다.
이름

2

국가 문자와 유니 코드 문자 클래스의 정확한 처리에 대해 매우 우려하는 경우 지금까지 내가 찾은 유일한 솔루션은 Python regex라이브러리 입니다. 둘 다 grepPerl(나의 완전한 놀랍게도!) 제대로 일을하지 않았다.

따라서 다음에 오는 정규식은 다음과 같습니다 \p{L}. 이것은 유니 코드 속성 속기 버전으로 알려져 있으며 정식 버전은 \p{Letter}또는 짝수 p\{General_Category=Letter}입니다. Letter그 자체는 복합 클래스이지만 자세한 내용은 다루지 않겠습니다 . 주제에 대한 최상의 참조는 여기 입니다.

파이썬 라이브러리는 언어에 내장되어 있지 않습니다 (내장 라이브러리의 대안입니다 re). 따라서 다음과 같이 설치해야합니다.

# pip install regex

그런 다음 다음과 같이 사용할 수 있습니다.

import regex
>>> regex.match(ur'\p{L}+', u'۱۲۳۴۵۶۷۸۹۰')
>>> regex.match(ur'\p{L}+', u'абвгд')
<regex.Match object; span=(0, 5), match=u'\u0430\u0431\u0432\u0433\u0434'>
>>> regex.match(ur'\p{L}+', u'123')
>>> regex.match(ur'\p{L}+', u'abcd')
<regex.Match object; span=(0, 4), match=u'abcd'>
>>> 

이 스크립트를 액세스 할 수있는 위치에 넣을 수도 있습니다.

#!/usr/bin/env python
import regex
import sys

if __name__ == "__main__":
    for match in regex.finditer(ur'\p{L}+', sys.argv[1].decode('utf-8')):
        print match.string

그리고 Emacs에서 다음과 같이 호출하십시오 (이 스크립트를에 저장했다고 가정하십시오 ~/bin).

(defun unicode-character-p ()
  (interactive)
  (let* ((current (char-after (point)))
         (result (shell-command-to-string
                  (format "~/bin/is-character.py '%c'" current))))
    (message
     (if (string= result "") "Character %c isn't a letter"
        "Character %c is a letter")
     current)))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.