악센트 문자에 대한 구체적인 Javascript 정규식 (이분법)


166

Stack Overflow ( 문자 교체 .. eh , JavaScript가 RegExp 등에 관한 유니 코드 표준을 따르지 않는 방법 등)를 살펴본 결과 질문에 대한 구체적인 답을 찾지 못했습니다.

How can JavaScript match for accented characters (those with diacritical marks)?

UI의 필드를 형식 : last_name, first_name (마지막 [쉼표 공간] 먼저) 과 일치 시키 도록 발음하고 분음 부호를 지원하려고하지만 JavaScript에서는 다른 언어 / 플랫폼보다 조금 더 어렵습니다.

분음 부호 지원을 추가 할 때까지 이것은 원래 버전이었습니다.

/^[a-zA-Z]+,\s[a-zA-Z]+$/

현재 지원을 추가하는 세 가지 방법 중 하나에 대해 토론 중입니다. 모두 테스트하고 작동했습니다 (적어도 어느 정도 "범위"가 두 번째 접근법인지는 알지 못합니다). 여기 있습니다:

유효한 것으로 받아들이고 자하는 모든 악센트 문자 (명확하고 지나치게 복잡함)를 명시 적으로 나열합니다.


var accentedCharacters = "àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ";
// Build the full regex
var regex = "^[a-zA-Z" + accentedCharacters + "]+,\\s[a-zA-Z" + accentedCharacters + "]+$";
// Create a RegExp from the string version
regexCompiled = new RegExp(regex);
// regexCompiled = /^[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+,\s[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+$/
  • 이것은에서 지원되는 악센트 부호 문자로 성 / 이름을 정확하게 일치 accentedCharacters시킵니다.

다른 접근법은 .문자 클래스 를 사용하여 더 간단한 표현을하는 것입니다.

var regex = /^.+,\s.+$/;
  • 이것은 적어도 다음과 같은 형식으로 거의 일치합니다 something, something. 괜찮습니다.

방금 찾은 마지막 접근 방식 이 더 간단 할 수 있습니다 ...

/^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
  • 그것은 테스트하고 작동하는 다양한 유니 코드 문자와 일치하지만, 미친 짓을 시도하지는 않았지만 교수진의 이름을 위해 언어 부서에서 볼 수있는 일반적인 것들입니다.

내 관심사는 다음과 같습니다.

  1. 첫 번째 해결책은 너무 제한적이며, 느슨하고 복잡합니다. 한두 글자를 잊어 버린 경우에는 변경해야하는데 이는 실용적이지 않습니다.
  2. 두 번째 해결책은 더 낫고 간결하지만 실제로 실제보다 훨씬 더 일치합니다. 나는에 실제 문서를 찾을 수 없습니다 정확히 무엇을 .일치, (온 테이블에서 "개행 문자를 제외한 모든 문자"단지 일반화 MDN을 ).
  3. 세 번째 해결책이 가장 정확한 것처럼 보이지만 문제가 있습니까? 나는 적어도 실제로, 유니 코드를 잘 알고 아니에요,하지만보고 코드 표 / 그 테이블의 계속 , \u00C0-\u017F적어도 내 예상 입력, 꽤 단단한 것 같다.

    • 교수진은 모국어 (예 : 아랍어, 중국어, 일본어 등)로 이름을 가진 양식을 제출하지 않으므로 라틴 문자 이외의 문자 집합에 대해 걱정할 필요가 없습니다.

따라서 실제 질문 :이 세 가지 접근법 중 어떤 것이 작업에 가장 적합합니까? 아니면 더 나은 솔루션이 있습니까?


1
더 복잡한 정규 표현식을 사용해야 할 특별한 이유가없는 것 같습니다. 가장 간단한 해결책은 "뭔가, 뭔가, 뭔가"와도 일치한다는 것입니다. 그것을 regex = /^[^,]+,\s[^,]+$/;막기 위해 같은 것을 사용할 수 있습니다 .
usr2564301

4
한 눈에, 첫 번째 이름은 일반적인 이름 "O'Donnell, Chris"또는 복합 성과 하이픈 또는 여러 성 (예 : 등)과 일치하지 않습니다. 가능한 모든 함정에 대해서는 거짓 프로그래머가 이름믿는다를 참조하십시오 .
usr2564301

" 원자 를 제외한 모든 항목과 일치 뉴 라인 :-) 사실은 꽤 정확".
BERGI

1
추가 라이브러리를 사용할 수 있다면 여기
stema

Jongware, 나는 실제로 내 기사에 대한 답을 찾기 위해 SO를 탐색하는 동안이 기사를 읽었습니다. 또한 하이픈과 아포스트로피 등을 완전히 잊어 버렸습니다. 국제적으로 먼저 만드는 데 더 관심이있었습니다 : P 그래도! 그리고 Stema, 나는 실제로 그 라이브러리를 보았고 라이브러리가 통합되지 않는 것이 좋았습니다.이 라이브러리는 모두 Google Apps Script에 있기 때문입니다. 외부 라이브러리를 통합하는 것은 악몽이 될 것입니다.이 경우 하나의 특정 필드에만 사용합니다 (이 경우) ... 종류 과잉의 : P
크리스 Cirefice

답변:


275

모든 악센트를 받아들이는 가장 쉬운 방법은 다음과 같습니다.

[A-zÀ-ú] // accepts lowercase and uppercase characters
[A-zÀ-ÿ] // as above but including letters with an umlaut (includes [ ] ^ \ × ÷)
[A-Za-zÀ-ÿ] // as above but not including [ ] ^ \
[A-Za-zÀ-ÖØ-öø-ÿ] // as above but not including [ ] ^ \ × ÷

숫자 순서로 나열된 문자는 https://unicode-table.com/en/ 을 참조 하십시오 .


2
잘 작동합니다, +1, 왜 작동하는지 자세히 설명해 주시겠습니까?
Pierre Henry

1
@PierreHenry는 -범위를 정의하며,이 기법은 문자 집합 의 문자 순서를 활용하여 연속 범위를 정의하여 문제에 대한 간결한 솔루션을 만듭니다.
Angad

8
하지 않습니다이 경기의 밑줄 (사이의 다른 비 단어 문자 Za)?
jcuenod

21
이것은 적어도 문자 [,], ^ 및 \와 일치하며이 중 어느 것도 포함하지 않아야합니다.
Nate

2
: 작동하지 않는,이 범위에있는 몇몇 문자는 악센트 문자는이 볼 (U + 00D7 예를 들어 곱셈 기호입니다)하지 unicode-table.com/en
제레미 Pouyet

39

악센트가 붙은 라틴어 범위 \u00C0-\u017F는 내 이름 데이터베이스에 충분하지 않으므로 정규 표현식을

[a-zA-Z\u00C0-\u024F]
[a-zA-Z\u00C0-\u024F\u1E00-\u1EFF] // includes even more Latin chars

이 코드 블록을 추가 \u00C0-\u024F했습니다 (한 번에 세 개의 인접한 블록 포함).

참고 \u00C0-\u00FF실제로 단지 일부 라틴 1 보충 . 이 범위는 인쇄 불가능한 제어 신호와 어색하게 배치 된 곱하기 × \u00D7및 나누기 ÷를 제외한 모든 기호를 건너 뜁니다 \u00F7.

[a-zA-Z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u024F] // exclude ×÷

더 많은 코드 포인트가 필요하면 Wikipedia의 유니 코드 문자 목록 에서 더 많은 범위를 찾을 수 있습니다 . 예를 들어 Latin Extended-C , DE를 추가 할 수도 있지만 지금은 역사학 자만 관심을 갖고 D 및 E 세트가 브라우저에서 올바르게 렌더링되지 않기 때문에 제외했습니다.

원래 정규 표현식 \u017F은 "Șenol"이라는 이름으로 시작됩니다. 에 따르면 FontSpace의 유니 코드 분석기 , 그 최초의 문자는 \u0218, 아래의 라틴 대문자 S WITH COMMA. (예, 보통 세 \u015E디야 (Cedilla -S) , "세놀 (Senol)"로 표시됩니다. 그러나 나는 터키로 날아가서 "당신의 이름을 잘못 입력하고 있습니다!")


1
상기 살펴 갖는 유니 코드 테이블 라틴어 블록을 , 당신도 포함해야한다고 생각 \ u1e00- \ u1eff, 내가하고 있어요 그래서[a-zA-Z\u00c0-\u024f\u1e00-\u1eff]
cprcrack

18

이 세 가지 방법 중 어떤 것이 작업에 가장 적합합니까?

작업에 따라 다릅니다 :-) 모든 라틴 문자와 강조된 버전을 정확하게 일치시키기 위해 유니 코드 범위는 아마도 최상의 솔루션을 제공 할 것입니다. 공백이 아닌 모든 문자로 확장 될 수 있으며 \S문자 클래스를 사용하여 수행 할 수 있습니다 .

UI의 필드가 형식과 일치하도록 강제합니다. last_name, first_name(마지막 [쉼표 공간])

여기에서 가장 기본적인 문제는 분음 부호가 아니라 공백입니다. 제목과 같이 여러 단어로 구성된 몇 가지 이름이 있습니다. 따라서 가장 일반적인 이름을 사용해야합니다. 즉 성을 제외한 쉼표를 제외한 모든 것을 허용합니다.

/[^,]+,\s[^,]+/

그러나 .문자 클래스가 있는 두 번째 솔루션 은 훌륭하지만 여러 쉼표 만 신경 쓰면됩니다.


흠, 아마 네 말이 맞아 아마 너무 복잡해 ... 당신이 제공 한 정규식을 설명해 주시겠습니까? 나는 정규 표현식으로 잠시 동안 일했지만 기본 사항 만 실제로 실제로 당신의 실제 행동에 대한 단서가 없습니다! 하
크리스 Cirefice

"쉼표 이외의 다른 것"을 의미 하는 부정 된 문자 클래스 입니다.
Bergi

아, 그래서 더 비슷해 any_character_not_a_comma, any_character_not_a_comma? 그것이 처음 읽을 때 생각한 것입니다. 거기에 세 개의 쉼표가 있으면 혼란스러워졌습니다.
Chris Cirefice

네 맞습니다. s공백 이없는 혼동에 대해 죄송합니다 …
Bergi

1
@ MateoTibaquirá 당신은 단순화 [^\s]할 수 있습니다\S
Bergi

15

XRegExp의 라이브러리가 유니 코드라는 이름의 플러그인 이 같은 작업을 해결하는 데 도움이됩니다.

<script src="xregexp.js"></script>
<script src="addons/unicode/unicode-base.js"></script>
<script>
  var unicodeWord = XRegExp("^\\p{L}+$");

  unicodeWord.test("Русский"); // true
  unicodeWord.test("日本語"); // true
  unicodeWord.test("العربية"); // true
</script>

질문에 대한 의견에서 언급되었지만 놓치기 쉽습니다. 이 답변을 제출 한 후에 만 ​​알았습니다.


니스, 실제로 유니 코드에서 정규 표현식을 필요로하지 않고 오히려 패턴을 사용해야한다는 것이 밝혀졌습니다 anything, anything. 이것은 미래의 독자들에게 유용 할 것입니다 :)
Chris Cirefice

12

이건 어때요?

/^[a-zA-ZÀ-ÖØ-öø-ÿ]+$/

2
일치하지 않습니다 Šš.
가주

5

이건 어때?

^([a-zA-Z]|[à-ú]|[À-Ú])+$

모든 단어를 악센트 부호가있는 문자와 일치 시키거나 일치시키지 않습니다.


2
그러나 OP는 악센트 부호가있는 문자 를 허용 하려고합니다 .
barbsan


3
/^[\pL\pM\p{Zs}.-]+$/u

설명:

  • \pL -모든 언어의 모든 문자와 일치
  • \pM -다른 캐릭터 (예 : 악센트, 움라우트, 둘러싸는 상자 등)와 결합되도록 의도 된 캐릭터를 불러들입니다.
  • \p{Zs} -보이지 않지만 공백을 차지하는 공백 문자와 일치
  • u -패턴 및 주제 문자열은 UTF-8로 처리됩니다.

제안 된 다른 정규 표현식 (예 :)과 달리이 규칙과 일치하지만이 페이지의 다른 [A-Za-zÀ-ÖØ-öø-ÿ]문자와 Šš는 일치하지 않는 모든 언어 별 문자에서 작동 합니다.

불행히도, 기본적으로 JavaScript는 이러한 클래스를 지원하지 않습니다. 그러나, xregexp예를 들어

const XRegExp = require('xregexp');

const isInputRealHumanName = (input: string): boolean => {
  return XRegExp('^[\\pL\\pM-]+ [\\pL\\pM-]+$', 'u').test(input);
};

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.