उच्चारण वर्णों के लिए ठोस जावास्क्रिप्ट रेक्स


166

मैंने स्टैक ओवरफ़्लो पर देखा है ( वर्णों को प्रतिस्थापित करते हुए .. एह , कैसे जावास्क्रिप्ट ने RegExp , आदि से संबंधित यूनिकोड मानक का पालन नहीं किया है ) और वास्तव में प्रश्न का एक ठोस उत्तर नहीं मिला है:

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

मैं प्रारूप का मिलान करने के लिए UI में एक फ़ील्ड को मजबूर कर रहा हूं: last_name, first_name (अंतिम [अल्पविराम स्थान] पहले) , और मैं डायसिटिक्स के लिए समर्थन प्रदान करना चाहता हूं, लेकिन जावास्क्रिप्ट में स्पष्ट रूप से यह अन्य भाषाओं / प्लेटफार्मों की तुलना में थोड़ा अधिक कठिन है।

यह मेरा मूल संस्करण था, जब तक कि मैं विशेष समर्थन जोड़ना नहीं चाहता था:

/^[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. दूसरा समाधान बेहतर है, संक्षिप्त है, लेकिन यह शायद उससे कहीं अधिक मेल खाता है जो वास्तव में होना चाहिए। मैं वास्तव में क्या .मेल खाता है, "नई लाइन चरित्र को छोड़कर किसी भी चरित्र के सामान्यीकरण" ( एमडीएन पर एक तालिका से ) का कोई भी वास्तविक दस्तावेज नहीं मिल सका ।
  3. तीसरा समाधान सबसे सटीक प्रतीत होता है, लेकिन क्या कोई गोचर है? मैं यूनिकोड से बहुत परिचित नहीं हूं, कम से कम अभ्यास में, लेकिन कोड तालिका / निरंतरता को देखते हुए , \u00C0-\u017Fयह बहुत ठोस प्रतीत होता है, कम से कम मेरे अपेक्षित इनपुट के लिए।

    • संकाय अपने मूल भाषा (जैसे, अरबी, चीनी, जापानी, आदि) में अपने नाम के साथ फॉर्म जमा नहीं करेंगे, इसलिए मुझे आउट-ऑफ-लैटिन-कैरेक्टर-सेट पात्रों के बारे में चिंता करने की ज़रूरत नहीं है

तो असली सवाल (ओं) : इन तीन दृष्टिकोणों में से कौन सा कार्य के लिए सबसे अनुकूल है? या बेहतर उपाय हैं?


1
अधिक जटिल रीजैक्स का उपयोग करने का कोई विशेष कारण नहीं लगता है। सबसे सरल समाधान के बारे में केवल एक चीज है, यह "कुछ, कुछ, कुछ" से भी मेल खाएगा। आप regex = /^[^,]+,\s[^,]+$/;इसे रोकने के लिए कुछ का उपयोग कर सकते हैं ।
usr2564301

4
एक नज़र में, पहला व्यक्ति सामान्य नाम "ओ'डोनेल, क्रिस" से मेल नहीं खाएगा और न ही एक हाइफ़न के साथ मिश्रित नाम, न ही कई अंतिम नाम (आदि)। केवल हर संभावित नुकसान के बारे में नामों के बारे में विश्वास करने वाले गलत कार्यक्रम देखें ।
usr2564301

" परमाणु के अलावा कुछ मेल खाता है नई-पंक्तियों " वास्तव में काफी सटीक है :-).
Bergi

1
यदि आपके लिए एक अतिरिक्त पुस्तकालय का उपयोग करना संभव है, तो आप यहाँ
stema

जोंगवेयर, मैंने वास्तव में सिर्फ उस लेख को पढ़ा था जब मैं अपने प्रश्न के उत्तर के लिए एसओ ब्राउज़ कर रहा था - मैं भी हाइफ़न और एपोस्ट्रोफ़ और इस तरह के बारे में पूरी तरह से भूल गया था, मैं पहले इसे अंतरराष्ट्रीय बनाने के साथ चिंतित था: पी मुझे खुशी है कि आप इसे लाए हैं। हालांकि! और स्टेमा, मैंने वास्तव में उस पुस्तकालय को देखा और मैं पुस्तकालयों को शामिल करने से बचता हूं क्योंकि यह सब Google Apps स्क्रिप्ट पर है - बाहरी पुस्तकालयों को शामिल करना एक बुरा सपना होगा, और मैं केवल एक विशेष क्षेत्र के लिए (इस मामले में) इसका उपयोग करूंगा ... overkill की तरह: पी
क्रिस 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, लेकिन क्या आप इस बारे में विस्तार से बता सकते हैं कि यह क्यों काम करता है?
पियरे हेनरी

1
@PierreHenry -एक सीमा को परिभाषित करता है, और यह तकनीक एक निरंतर सीमा को परिभाषित करने के लिए चारसेट में वर्णों के क्रम का शोषण करती है, जिससे समस्या का एक सुपर संक्षिप्त समाधान हो जाता है
अंगद

8
क्या यह मैच अंडरस्कोर (और अन्य गैर-शब्द अक्षर के बीच Zऔर a) नहीं होगा?
jcuenod

21
यह कम से कम वर्णों [,], ^, और \ से मेल खाता है, जिनमें से कोई भी शामिल नहीं होना चाहिए।
नट

2
काम नहीं कर रहा है, इस श्रेणी के कुछ अक्षर उच्चारण अक्षर नहीं हैं (U + 00D7 उदाहरण के लिए गुणन चिह्न है) इसे देखें: unicode-table.com/en
Jérémy 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 ×÷

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

मूल रेगेक्स \u017F""enol" नाम पर बोर्कड पर रोक । फॉन्टस्पेस के यूनिकोड एनालाइजर के अनुसार , वह पहला चरित्र है \u0218, लातिन कैपिटल लेटरर एस विथ कॉममा बलो । (हाँ, यह आमतौर पर एक सेडिला-एस के साथ वर्तनी है \u015E, ".enol।" लेकिन मैं उसे बताने के लिए तुर्की नहीं जा रहा हूँ, "आप अपना नाम गलत बता रहे हैं!")


1
यूनिकोड तालिका लैटिन ब्लॉक पर एक नज़र रखने के बाद , मुझे लगता है कि आपको \ u1e00- \ u1eff को भी शामिल करना चाहिए, इसलिए मैं कर रहा हूँ[a-zA-Z\u00c0-\u024f\u1e00-\u1eff]
cprcrack

18

इन तीन दृष्टिकोणों में से कौन सा कार्य के लिए सबसे अनुकूल है?

कार्य पर निर्भर करता है :-) बिल्कुल सभी लैटिन वर्णों और उनके उच्चारण संस्करणों से मेल खाने के लिए, यूनिकोड पर्वतमाला शायद सबसे अच्छा समाधान प्रदान करती हैं। उन्हें सभी गैर-व्हाट्सएप चरित्रों तक बढ़ाया जा सकता है, जो \Sचरित्र वर्ग का उपयोग करके किया जा सकता है ।

मैं प्रारूप का मिलान करने के लिए UI में एक फ़ील्ड मजबूर कर रहा हूं: last_name, first_name(अंतिम [अल्पविराम स्थान] पहले)

सबसे बुनियादी समस्या जो मैं यहाँ देख रहा हूँ, वह डाइटेक्टिक्स नहीं है, बल्कि व्हॉट्सएप है। कुछ नाम ऐसे हैं जिनमें कई शब्द शामिल हैं, जैसे शीर्षक। तो आपको सबसे सामान्य के साथ जाना चाहिए, जो सब कुछ की अनुमति दे रहा है लेकिन अल्पविराम जो पहले नाम से अलग है:

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

लेकिन .चरित्र वर्ग के साथ आपका दूसरा समाधान ठीक है, आपको केवल तब कई अल्पविरामों की देखभाल करने की आवश्यकता हो सकती है।


हम्म, शायद तुम सही हो। मैंने शायद इसे अधिक जटिल बना दिया ... क्या आप अपने द्वारा प्रदान किए गए रेगेक्स की व्याख्या कर सकते हैं? मैं थोड़ी देर के लिए regex के साथ काम कर रहा हूं, लेकिन केवल मूल सामान, और वास्तव में मुझे कोई सुराग नहीं है कि आपका वास्तव में क्या होता है! हा
क्रिस क्रेफ़िस

यह एक नकारात्मक चरित्र वर्ग है - जिसका अर्थ है "अल्पविराम के अलावा कुछ भी"।
बरगी

आह, तो यह और अधिक पसंद है any_character_not_a_comma, any_character_not_a_comma? यही मैंने सोचा था कि जब मैंने पहली बार इसे पढ़ा था, तो मुझे उस समय भ्रम हुआ जब मैंने तीन कॉमा को देखा।
क्रिस क्रेफ़िस

हाँ बिल्कुल। s
व्हॉट्सएप

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>

यह टिप्पणी करने के लिए सवाल में उल्लेख किया है, लेकिन यह याद करना आसान है। मैंने यह उत्तर प्रस्तुत करने के बाद ही इस पर ध्यान दिया है।


अच्छा, यह पता चला है कि मुझे वास्तव में यूनिकोड पर rexx की आवश्यकता नहीं थी, बल्कि पैटर्न पर anything, anything। यह भविष्य के पाठकों के लिए उपयोगी होगा :)
क्रिस साइरफाइस

12

इस बारे में कैसा है?

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

2
मेल नहीं खाता Šš
गजस

5

इस बारे में क्या?

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

यह हर शब्द उच्चारण पात्रों के साथ मेल खाएगा या नहीं।


2
लेकिन ओपी उच्चारण पात्रों को अनुमति देना चाहता है ।
बारबसन


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

स्पष्टीकरण:

  • \pL - किसी भी भाषा के किसी भी प्रकार के पत्र से मेल खाता है
  • \pM - एक चरित्र को दूसरे वर्ण के साथ संयोजित करने का इरादा रखता है (जैसे उच्चारण, ओमलैट्स, एनक्लोजिंग बॉक्स, आदि)
  • \p{Zs} - एक व्हाट्सएप चरित्र से मेल खाता है जो अदृश्य है, लेकिन जगह नहीं लेता है
  • u - पैटर्न और विषय के तार को UTF-8 के रूप में माना जाता है

अन्य प्रस्तावित रेगेक्स (जैसे [A-Za-zÀ-ÖØ-öø-ÿ]) के विपरीत , यह सभी भाषा विशिष्ट वर्णों के साथ काम करेगा, उदाहरण के Ššलिए इस नियम से मेल खाता है, लेकिन इस पृष्ठ पर दूसरों द्वारा मिलान नहीं किया गया है।

दुर्भाग्य से, मूल रूप से जावास्क्रिप्ट इन वर्गों का समर्थन नहीं करता है। हालाँकि, आप उपयोग कर सकते हैं xregexp, जैसे

const XRegExp = require('xregexp');

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

1

आप का उपयोग करके वर्णमाला से diacritics निकाल सकते हैं:

var str = "résumé"`
str.normalize('NFD').replace(/[\u0300-\u036f]/g, '')` // returns resume

यह सभी diacritical निशान हटा देगा, और फिर उस पर अपना regex प्रदर्शन करेगा

संदर्भ:

https://thread.engineering/2018-08-29-searching-and-sorting-text-with-diacritical-marks-in-javascript/

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.