Priyankar Bose
Priyankar Bose

Reputation: 1

Remove everything from text except Hindi and English letters and numbers and punctuation

I have a text which is mixed in English and Hindi and I want to remove all the characters except Hindi and English characters and numbers and punctuation. That way, I can get rid of "(", ")","@", etc. Please consider the text below.

text = नई दिल्ली। Navjot Singh Sidhu Resigns. पंजाब विधानसभा चुनाव से पहले पंजाब कांग्रेस में कई बड़े बदलाव देखने को मिल रहे हैं। पहले कैप्टन अमरिंदर सिंह का पंजाब के मुख्यमंत्री पद से इस्तीफा दिया, उसके बाद चरणजीत सिंह चन्नी को राज्य का नया मुख्यमंत्री बनाया गया। वहीं अब नवजोत सिंह सिद्धू ने पंजाब कांग्रेस अध्यक्ष पद से इस्तीफा दे दिया है।I told you so…he is not a stable man and not fit for the border state of punjab.— Capt.Amarinder Singh (@capt_amarinder) September 28, 2021सोनिया गांधी को लिखा पत्र बता दें कि नवजोत सिंह सिद्धू ने काग्रेस अध्यक्ष सोनिया गांधी को एक पत्र लिखकर इस संबंध में जानकारी दी है। पत्र में सिद्धू ने यह भी कह कि वे कांग्रेस का हिस्सा बने रहेंगे।pic.twitter.com/L5wdRql5t3— Navjot Singh Sidhu (@sherryontopp) September 28, 2021

Upvotes: 0

Views: 335

Answers (2)

Andj
Andj

Reputation: 1447

The answer given by @atteggiani will work but requires a bit of a tweak.

The Unicode definition of \w and the Python definition differ.

If I take the first sentence of the example text, and use the pattern r'[^\w\s\.,:;]+':

import re
sentence = "नई दिल्ली। Navjot Singh Sidhu Resigns."
pattern = r'[^\w\s\.,:;]+'
result_re = re.sub(pattern, '', sentence)
print(result_re)
# नई दलल Navjot Singh Sidhu Resigns.

The pattern used with the re module removes Vowel Sign I (U+093F), Virama (U+094D), Vowel Sign II (U+0940). It also removed Devanagari punctuation.

If we install the regex module:

pip install regex

then

import regex as re
sentence = "नई दिल्ली। Navjot Singh Sidhu Resigns."
pattern = r'[^\w\s\.,:;]+'
result_regex = re.sub(pattern, '', sentence)
print(result_regex)
# नई दिल्ली Navjot Singh Sidhu Resigns.

This will retain the Devanagari letters that re module striped out.

The regex module can be used as a drop in replacement for the re module, but is compatible with Unicode, and should be used instead of re for any regular expressions with non-English text.

The OP wants to keep English and Hindi text, numbers and certain punctuation, so pattern could be rewritten as r'[^\w\s\d\.,:;।॥?\-]+' and can be adjusted for other punctuation.

This gives:

import regex as re
text = "नई दिल्ली। Navjot Singh Sidhu Resigns. पंजाब विधानसभा चुनाव से पहले पंजाब कांग्रेस में कई बड़े बदलाव देखने को मिल रहे हैं। पहले कैप्टन अमरिंदर सिंह का पंजाब के मुख्यमंत्री पद से इस्तीफा दिया, उसके बाद चरणजीत सिंह चन्नी को राज्य का नया मुख्यमंत्री बनाया गया। वहीं अब नवजोत सिंह सिद्धू ने पंजाब कांग्रेस अध्यक्ष पद से इस्तीफा दे दिया है।I told you so…he is not a stable man and not fit for the border state of punjab.— Capt.Amarinder Singh (@capt_amarinder) September 28, 2021सोनिया गांधी को लिखा पत्र बता दें कि नवजोत सिंह सिद्धू ने काग्रेस अध्यक्ष सोनिया गांधी को एक पत्र लिखकर इस संबंध में जानकारी दी है। पत्र में सिद्धू ने यह भी कह कि वे कांग्रेस का हिस्सा बने रहेंगे।pic.twitter.com/L5wdRql5t3— Navjot Singh Sidhu (@sherryontopp) September 28, 2021"
pattern = r'[^\w\s\d\.,:;।॥?\-]+'
result = re.sub(pattern, '', text)
print(result)
# नई दिल्ली। Navjot Singh Sidhu Resigns. पंजाब विधानसभा चुनाव से पहले पंजाब कांग्रेस में कई बड़े बदलाव देखने को मिल रहे हैं। पहले कैप्टन अमरिंदर सिंह का पंजाब के मुख्यमंत्री पद से इस्तीफा दिया, उसके बाद चरणजीत सिंह चन्नी को राज्य का नया मुख्यमंत्री बनाया गया। वहीं अब नवजोत सिंह सिद्धू ने पंजाब कांग्रेस अध्यक्ष पद से इस्तीफा दे दिया है।I told you sohe is not a stable man and not fit for the border state of punjab. Capt.Amarinder Singh capt_amarinder September 28, 2021सोनिया गांधी को लिखा पत्र बता दें कि नवजोत सिंह सिद्धू ने काग्रेस अध्यक्ष सोनिया गांधी को एक पत्र लिखकर इस संबंध में जानकारी दी है। पत्र में सिद्धू ने यह भी कह कि वे कांग्रेस का हिस्सा बने रहेंगे।pic.twitter.comL5wdRql5t3 Navjot Singh Sidhu sherryontopp September 28, 2021

This will keep other languages as well. We could refine it as suggested in the other answer, and only include letters used in English and Hindi, but this will capture some non-Hindi Devanagari text.

For English: a-zA-Z. For Hindi: [ँ-ःअ-ऍए-ऑओ-नप-रलळव-ह़-ॅे-ॉो-्ॐ\u200c\u200d]. And the pattern: r'[^ँ-ःअ-ऍए-ऑओ-नप-रलळव-ह़-ॅे-ॉो-्ॐ\u200c\u200da-zA-Z\s\d\.,:;।॥?\-]+'.

import regex as re
pattern = r'[^ँ-ःअ-ऍए-ऑओ-नप-रलळव-ह़-ॅे-ॉो-्ॐ\u200c\u200da-zA-Z\s\d\.,:;।॥?\-]+'
alt_result = re.sub(pattern, '', text)
print(alt_result)
# नई दिल्ली। Navjot Singh Sidhu Resigns. पंजाब विधानसभा चुनाव से पहले पंजाब कांग्रेस में कई बड़े बदलाव देखने को मिल रहे हैं। पहले कैप्टन अमरिंदर सिंह का पंजाब के मुख्यमंत्री पद से इस्तीफा दिया, उसके बाद चरणजीत सिंह चन्नी को राज्य का नया मुख्यमंत्री बनाया गया। वहीं अब नवजोत सिंह सिद्धू ने पंजाब कांग्रेस अध्यक्ष पद से इस्तीफा दे दिया है।I told you sohe is not a stable man and not fit for the border state of punjab. Capt.Amarinder Singh captamarinder September 28, 2021सोनिया गांधी को लिखा पत्र बता दें कि नवजोत सिंह सिद्धू ने काग्रेस अध्यक्ष सोनिया गांधी को एक पत्र लिखकर इस संबंध में जानकारी दी है। पत्र में सिद्धू ने यह भी कह कि वे कांग्रेस का हिस्सा बने रहेंगे।pic.twitter.comL5wdRql5t3 Navjot Singh Sidhu sherryontopp September 28, 2021

Assuming all content is in English or Hindi, a simpler approach is to just remove the unwanted punctuation, i.e. r'[()@]+':

pattern = r'[()@]+'
new_result = re.sub(pattern, '', text)
print(new_result)
# नई दिल्ली। Navjot Singh Sidhu Resigns. पंजाब विधानसभा चुनाव से पहले पंजाब कांग्रेस में कई बड़े बदलाव देखने को मिल रहे हैं। पहले कैप्टन अमरिंदर सिंह का पंजाब के मुख्यमंत्री पद से इस्तीफा दिया, उसके बाद चरणजीत सिंह चन्नी को राज्य का नया मुख्यमंत्री बनाया गया। वहीं अब नवजोत सिंह सिद्धू ने पंजाब कांग्रेस अध्यक्ष पद से इस्तीफा दे दिया है।I told you so…he is not a stable man and not fit for the border state of punjab.— Capt.Amarinder Singh capt_amarinder September 28, 2021सोनिया गांधी को लिखा पत्र बता दें कि नवजोत सिंह सिद्धू ने काग्रेस अध्यक्ष सोनिया गांधी को एक पत्र लिखकर इस संबंध में जानकारी दी है। पत्र में सिद्धू ने यह भी कह कि वे कांग्रेस का हिस्सा बने रहेंगे।pic.twitter.com/L5wdRql5t3— Navjot Singh Sidhu sherryontopp September 28, 2021

EDIT:

Above, I used an explicit set of characters for Hindi. The Common Locale Data Repository (CLDR) contains exemplar characters. I used icu4c and PyICU to create a pattern to use for Hindi characters. There are main (standard) exemplars that are required for a locale and I have also added auxillary characters that are used for loan words, representing foreign words, etc.

import icu
# Build a LocaleData object for Hindi locale.
ld = icu.LocaleData('hi')
# A UnicodeSet object containing main (standard) exemplar characters
exemplars_main = ld.getExemplarSet(icu.ULocaleDataExemplarSetType.ES_STANDARD)
# A UnicodeSet object containing auxillary exemplar characters
exemplars_aux = ld.getExemplarSet(icu.ULocaleDataExemplarSetType.ES_AUXILIARY)
# Union of the two UnicodeSets
exemplars = exemplars_main.addAll(exemplars_aux)
# Create a regex pattern of the UnicodeSet
hindi_pattern = exemplars.toPattern()

Upvotes: 1

atteggiani
atteggiani

Reputation: 480

You can use python regex method re.sub(pattern,substring,string) which substitutes matching pattern in the string with substring. In your case, since you want to delete the characters, you would substitute with an empty string '':

import re
pattern=r'[^\w\s]+'
re.sub(pattern, '', text)

Explanation

[^...] used to indicate a set of characters NOT to be matchded (any character in that set will NOT be matched);

\w for Unicode (str) patterns matches Unicode word characters; this includes alphanumeric characters (as defined by str.isalnum()) as well as the underscore (_);

\s for Unicode (str) patterns matches Unicode whitespace characters (which includes [ \t\n\r\f\v], and also many other characters, for example the non-breaking spaces mandated by typography rules in many languages);

+ Causes the resulting regex to match 1 or more repetitions of the preceding regex.

from Python regex documentation.

So this means anything that is not a unicode alphanumeric character or a unicode space will get deleted (replaced with an empty string).

You can modify the matching pattern in case you want to include/exclude other characters. For example, if you want to keep punctuation, you would have:

pattern = r'[^\w\s\.,:;]+'

If, instead, you want to also delete underscores (_), you will have to change \w into explicit set of characters you want to keep, in your case:

pattern=r'[^a-zA-Z0-9\u0900-\u0954\s]+'

\u0900-\u0954 are unicode characters from U+900 to U+0954 which are the Devanagari (Unicode block) characters used in Hindi.

Upvotes: 0

Related Questions