2016-02-13 6 views
6

के साथ रेगेक्स मैच कैरेक्टर एक विशिष्ट डायक्रिटिक वाले चरित्र के लिए एक मैच निर्दिष्ट करने के लिए रेगेक्स में कोई तरीका है? चलिए उदाहरण के लिए एक गंभीर उच्चारण कहते हैं।विशिष्ट डायक्रिटिक

/[àầằèềḕìǹòồṑùǜừẁỳ]/i 

यह काफी थकाऊ है: यह करने के लिए लंबा रास्ता तय करना, Wikipedia page on the grave accent के लिए जाने के पात्रों यह पता चलता है के सभी कॉपी कर उन्हें उनमें से बाहर एक चरित्र वर्ग बनाने के लिए है। मैं एक यूनिकोड संपत्ति की उम्मीद कर रहा था जैसे \p{hasGraveAccent}, लेकिन मुझे ऐसा कुछ भी नहीं मिला। समाधान के लिए खोज केवल डायक्रिटिक्स को अनदेखा करते समय पात्रों से मेल खाने की कोशिश करने वाले लोगों के प्रश्नों के साथ आता है, जिसमें किसी प्रकार का सामान्यीकरण करना शामिल है, जो मैं नहीं चाहता हूं।

+0

यदि यह एक संयोजन चरित्र है, तो यह संभव हो सकता है [यूनिकोड कोडपॉइंट्स की एक सूची उत्पन्न करना] (http://stackoverflow.com/questions/17051732/algorithm-to-check-for-combining-characters-in-unicode)। – kba

+0

एकल अक्षरों से बाहर एक चरित्र वर्ग विश्वसनीय नहीं है और काम नहीं करेगा।यह केवल स्ट्रिंग एनएफसी (सामान्यीकरण फॉर्म बनाये गये) से मेल खाने वाले प्रीकॉम्ज्ड अक्षरों के लिए काम करेगा। दो या दो से अधिक diacritics वाले अधिकांश पात्रों में कोई पूर्वकल्पित चरित्र नहीं है। अर्थात। उनमें एक से अधिक कोड पॉइंट (= यूनिकोड भाषण में वर्ण) शामिल हैं। यदि आप उन्हें एक चरित्र वर्ग में कॉपी और पेस्ट करते हैं तो डायक्रिटिक अभी भी एक वर्ण है और लक्ष्य स्ट्रिंग में एक ही एकल डायक्रिटिक्स से मेल खाता है। –

उत्तर

0

यह एक मुश्किल सवाल है, लेकिन यह संभव है। सबसे पहले, आपको यूनिकोड स्ट्रिंग को 4 रूपों में से एक में सामान्य करना होगा। सामान्यीकरण पर जानकारी here है, और विभिन्न सामान्यीकरण के साथ चरित्र उदाहरणों का नक्शा here है, और सामान्यीकृत वर्णों के लिए एक अच्छा चार्ट here है। अनिवार्य रूप से, सामान्यीकरण केवल यह सुनिश्चित करता है कि सभी वर्ण एक ही प्रारूप में हैं जब diacritics को संभालने। गोलांग के लिए इसका बहुत अच्छा समर्थन है, और अधिकांश भाषाओं में पुस्तकालयों को ऐसा करने के लिए होना चाहिए।

तो मेरे उदाहरण के लिए, अपनी स्ट्रिंग को "सामान्यीकरण फ़ॉर्म डी" (एनएफडी) और utf32 में परिवर्तित करें, इसलिए सभी यूनिकोड वर्ण 4 बाइट्स में उनके कोड पॉइंट हैं।

कब्र उच्चारण के लिए सभी विशिष्ट वर्णों में चरित्र के बगल में 0x0300 है। तो आप ....\x00\x00\x03\x00 के लिए एसीआई मोड (यूनिकोड मोड नहीं) में एक नियमित अभिव्यक्ति खोज कर सकते हैं। वहां से आपको उस रनवे स्थान को निकालना होगा जिसमें यह है। यह आपके द्वारा उपयोग किए जा रहे एन्कोडिंग के आधार पर विभिन्न विधियों के साथ किया जा सकता है।

तो यदि आप 4 के विभाजन पर उतरते हैं, तो आप इसे एक वैध चरित्र जानेंगे।

इसके अलावा, ऐसा करने के लिए कोई आधिकारिक perl चरित्र समूह नहीं हैं।

एक उदाहरण के रूप

पर्ल कोड:

use Encode; 
use Unicode::Normalize; 

$StartUTF8='xàaâèaê'; 
$PerlEncoded=decode('utf8', $StartUTF8); 
$PerlNormalized=NFD($PerlEncoded); 
$UTF32Normalized=encode('utf32', $PerlNormalized); 

while($UTF32Normalized =~ /(....\x00\x00\x03\x00)/gs) { 
    $Pos=pos($UTF32Normalized)-8; 
    if($Pos%4==0) { 
     print("$Pos\n"); 
    } 
} 

लेकिन इस बिंदु पर, आप के रूप में अच्छी सिर्फ एक पाश के लिए वर्णों से अधिक कर किया जा सकता है: - \

मैं भी स्थिति की जरूरत के बिना मिलान करने की कोशिश की // सी का उपयोग करके परीक्षण करें, लेकिन किसी कारण से यह काम नहीं करेगा।

/^(?:....)*?(....\x00\x00\x03\x00)/gcs

+0

यूटीएफ 32 में कनवर्ट करने का कोई मतलब नहीं है (और, यदि आप मानते हैं कि परिणाम यूटीएफ -32LE है, तो इसे इसे मौका छोड़ने के बजाय इसे परिवर्तित करना चाहिए)। साथ ही, धारणा है कि गंभीर चरित्र तुरंत मूल चरित्र का पालन करता है, जब ग्लिफ में एक से अधिक डायक्रिटिक होते हैं। वास्तव में – rici

+0

। यह बहुत निष्फल शोध और परीक्षण था – Dakusan

1

यह कुछ सीमाओं के साथ संभव है।

#!perl 

use strict; 
use warnings; 

use Encode; 
use Unicode::Normalize; 
use charnames qw(); 
use utf8; # source is utf-8 

binmode(STDOUT, ":utf8"); # print in utf-8 

my $utf8_string = 'xàaâèaêòͤ'; 

my $nfd_string = NFD($utf8_string); # decompose 

my @chars_with_grave = $nfd_string =~ 
    m/ 
    (
     \p{L}   # one letter 
     \p{M}*   # 0 or more marks 
     \N{COMBINING GRAVE ACCENT} 
     \p{M}*   # 0 or more marks 
    ) 
    /xmsg; 

print join(', ',@chars_with_grave), "\n"; 

यह प्रिंट

$ perl utf_match_grave.pl 
à, è, òͤ 

नोट: के रूप में संयुक्त संपादित क्षेत्र में पात्रों सही ढंग से प्रदर्शित कर रहे हैं, लेकिन stackoverflow renders उन्हें गलत तरीके से अलग।

इसे मूल चरित्र के रूप में एक पत्र की आवश्यकता है। अन्य मूल पात्रों के लिए regex बदलें। मार्क \p{M} शायद वही नहीं है जो आप चाहते हैं, बेहतर होना चाहिए।

संबंधित मुद्दे