# فناوری جاوا > برنامه‌نویسی جاوا >  حذف حروف اضافه با regex

## shabgardetanha

سلام دوستان
من میخوام حروف اضافه کلمات مثل Heeeellllloooo که کلمه Hello بوده رو حذف کنم
یا Gooood که good بوده
اما نمیدونم چطور با عبارت منظم بنویسم؟ 
خواهش میکنم راهنمایی کنید
ممنون

----------


## vahid-p

با عبارت منظم میتونی حروفی که مثلا بیش از یکبار کنار هم تکرار شدن رو استخراج کنید. اما اینکه مستقیم حذف بشن نه. اما این کار رو راحتتر با یک حلقه ساده for هم میتونید بنویسید. اما مشکلی که وجود داره الگوریتمی برای اینکه بتونید تشخیص بدید کجا دو حرف یکیشو حذف کنه و کجا نه وجود نداره (بدون داشتن دیکشنری). یعنی Heeeellllloooo به helo تبدیل میشه یا gooood به god!
حتی اگر دیکشنری داشته باشید هم مثلا همین مثال gooood هم good صحیحه و هم god.

----------


## vahid-p

مثال:
import java.util.regex.Matcher;import java.util.regex.Pattern;


public class Main {
    public static void main(String[] args) {
        String text = "Heeelloooo gooood, fine";
        System.out.println(removeRepeatedChar(text));
    }
    
    public static String removeRepeatedChar(String str)
    {
        String myPattern = "(.)\\1{1,}";
        int start = 0;
        String retStr = "";
        
        Pattern p = Pattern.compile(myPattern,Pattern.CASE_INSENSITIVE  );
        Matcher m = p.matcher(str);
        while (m.find()) {
            retStr += str.substring(start, m.start())+String.valueOf(str.charAt(m.start()));
            start = m.end();
        }
        retStr +=str.substring(start);
        return retStr;
    }
}

خروجی:
Helo god, fine


یا بدون regex:
    public static String removeRepeatedChar(String str) {        Character prevChar = null;
        StringBuilder retStr = new StringBuilder("");
        int i = 0;
        for (i = 0; i < str.length(); i++) {
            if (prevChar == null || prevChar != str.charAt(i)) {
                prevChar = str.charAt(i);
                retStr.append(str.substring(i, i+1));
            }
        }
        return retStr.toString();
    }

این جواب میده هر چند بهتر از این هم میشه نوشت.

----------


## shabgardetanha

جناب مهندس
خیلی تشکر
من باید خودم دیکشنری ایجاد کنم؟ ممکنه بفرمایید به چه صورت؟
جناب مهندس . من میخوام عبارت منظم رو در برنامه رپیدماینر بنویسم. کد عبارت منظم شما رو نوشتم اما هیچ اتفاقی نیفتاد ممکنه راهنمایی بفرمایید؟؟
ببینید
۱.jpg

----------


## ghamgin

سلام دوستان
من میخوام این کار رو روی یک ستون فایل اکسل که حاوی متن هست و (دو ستون دارم و ۵۰۰ سطر) اعمال کنم. چکار باید انجام بده.؟؟ممنون

----------


## vahid-p

دوست عزیز اینجا انجمن جاواست.
اون \\ در عبارت منظم هم برای رشته در جاوا لازمه چون \ یک کاراکتر خاص هست و...
اگر برای جا دیگه ای میخواید از یک \ استفاده کنید.
من کد و خروجی رو هم نوشتم اگر اجرا کنید جواب میده. اگر هم زبان جاوا کار نمیکنید، این موضوع رو جای دیگه ای باید مطرح کنید چون اینجا مختص جاواست و پیشفرض اینه سوالتون در مورد جاوا باشه.

به هر حال برای تست regex ها میتونید از سایت زیر استفاده کنید که به صورت تعاملی خروجیش هم چک کنید. البته حذف و... نمیکنه و فقط میتونید regex هاتون رو چک کنید:
https://regexr.com

در قسمت expression بنویسید:
/(.)\1{1,}/g
و در قسمت text هم هر متنی که میخواید رو تست کنید مثلا همین:
Heeelloooo gooood, fine

میبینید که حروف تکراری رو تشخیص میده.

همچنین سوالتون تشابه زیادی به این سوال داره که همزمان پرسیدید: https://barnamenevis.org/showthread.php?547734

----------


## shabgardetanha

سلام
خیلی متشکرم
ببخشید  حق با شماست
اما برنامه ای که گفتم به زبان جاوا هست.
الان میشه در عبارت منظم به جای اینکه گفته بشه بیش از یکبار تکرار حرف، بگم بالای دوبار تکرار بقیه حذف بشه؟ 
و اینکه چطور میشه گفت کلمه بعد از علامت @ رو حذف کنم؟ 
ممنون میشم محبت کرده و این موارد رو هم راهنمایی کنید
ممنون

----------


## ghamgin

سلام
دوست عزیز مگه امکان پرسیدن سوال مشابه وجود نداره؟ من از چند روز قبل این مشکل رو دارم و توی تالارهای مختلف پرسیدم که بتونم با هر زبانی فایل اکسل رو بخونم و ویرایش کنم اما هیچ کسی پاسخ نداد...
ممنون از راهنمایی شما...

----------


## vahid-p

اول یه عذرخواهی بکنم چون من به نام کاربریتون توجه نکردم و این تاپیک اولش با پست shabgardetanha شروع شده ولی دقت نکردم در مورد اکسل شما پرسیدید و کلا همه چی قاطی شده بود!



> دوست عزیز مگه امکان پرسیدن سوال مشابه وجود نداره؟


نه چه ایرادی داره؟ برای اون یکی دوست عزیز هم این تاپیک رو لینک کردم تا از مطالبش استفاده کنن و شما هم همچنین میتونید از چیزهایی که اونجا گفته شده استفاده کنید.


اما در مورد سوالات برنامه نویسی:



> الان میشه در عبارت منظم به جای اینکه گفته بشه بیش از یکبار تکرار حرف، بگم بالای دوبار تکرار بقیه حذف بشه؟


به جای عدد 1 در {1,} بنویسید 2.



> و اینکه چطور میشه گفت کلمه بعد از علامت @ رو حذف کنم؟


بهترین کار اینه که شما @ و کلمه بعدش رو پیدا کنید ولی موقع حذف کردن کاراکتر اول یعنی @ رو حفظ کنید و بقیش رو حذف کنید. نکته ای که لازمه باز تکرار کنم اینه regex فقط اون الگو رو پیدا میکنه و حذفش با شماست. تو کدی که نوشتم هم کاراکتر اول حفظ میشه پس فقط کافیه عبارت منظم رو دستکاری کنید. در پست قبلی هم گفتم از اون سایت استفاده کنید تا بتونید regex هاتون رو تست کنید و خودش هم راهنمایی هایی داره.
به هر حال مهمه کلمه یعنی چی. اگر فقط حروف a تا z باشه میتونی اینطور بنویسی:
@[a-z]+
که البته حروف کوچک رو تشخیص میده و حروف بزرگ نباید وسط کلمه باشه هر چند در کدی که نوشتیم CASE_INSENSITIVE تنظیم شده پس مسئله ای با حروف بزرگ نداره و تشخیص میده. اما اگر برای جایی میخوایید که حروف بزرگ و کوچک رو باید تو regex بیارید به این صورت بنویسید:
@[a-z,A-Z]+




> من باید خودم دیکشنری ایجاد کنم؟ ممکنه بفرمایید به چه صورت؟


دیکشنری نیاز به فایلی دارید که اکثر کلمات انگلیسی رو داشته باشه. من چنین فایلی ندارم ولی در اینترنت هست و اونوقت بحث ساختمان داده و... هم مطرح میشه که در حالت ساده می تونید در HashMap ذخیره کنید و اونوقت برای پیدا کردنش مشکلات دیگه ای هم هست (چون مثلا heeellooo خودش میتونه چندین و چند حالت مختلف مثل heellooo hellooo helloo hello helo heelloo hو.... باشه) که کاریه که اینجا نمیشه صحبتش کرد و هر قسمت خودش بحث مفصلی ممکنه داشته باشه

----------


## ghamgin

سلام
قصد جسارت نداشتم
ممنون که راهنمایی می کنید
ممکنه بگید چطور فایل اکسل در جاوا بخونم و روی یک ستون اعمال کنم و مجدد ذخیره کنم؟
ممنون میشم راهنمایی کنید

----------


## shabgardetanha

سلام
یه دنیا ممنون
فقط من میخوام
کلمه بعد @ و خود @ باهم پاک بشه و جاش فاصله قرار بگیره امکانش هست؟
توی اون سایت چظور باید عبارت منظم چک کنم؟
منون بازم

----------


## shabgardetanha

برای کلمه goood کار نکرد . ۲ نوشتم
Heeelloooo gooood, fine


"(.)\\1{2,}"


Hello god, fine

----------


## vahid-p

> ممکنه بگید چطور فایل اکسل در جاوا بخونم و روی یک ستون اعمال کنم و مجدد ذخیره کنم؟


تو لینک تاپیک مشابهی که گفتم بیشتر بحث شده، میتونید مراجعه کنید.




> برای کلمه goood کار نکرد . ۲ نوشتم


برای من جواب میده. احتمالا یه جای کار اشتباه کردید.

کد مجدد:
import java.util.regex.Matcher;import java.util.regex.Pattern; 
 
public class Main {
    public static void main(String[] args) {
        System.out.println(removeRepeatedChar("Heeelloooo goood, fine"));
        System.out.println(removeRepeatedChar("goood"));
        System.out.println(removeRepeatedChar("good"));
    }
     
    public static String removeRepeatedChar(String str)
    {
        String myPattern = "(.)\\1{2,}";
        int start = 0;
        String retStr = "";
         
        Pattern p = Pattern.compile(myPattern,Pattern.CASE_INSENSITIVE  );
        Matcher m = p.matcher(str);
        while (m.find()) {
            retStr += str.substring(start, m.start())+String.valueOf(str.charAt(m.start()));
            start = m.end();
        }
        retStr +=str.substring(start);
        return retStr;
    }
}

خروجی:
Hello god, finegod
good
البته اگر بیشتر از دو تا بود به یک حرف تبدیل میکنه. اگر نه باید به جز str.chatAt(m.start()) کلمه m.start()+1 هم اضافه کنید. خلاصه یکم با این کد کار کنید متوجه میشید.




> کلمه بعد @ و خود @ باهم پاک بشه و جاش فاصله قرار بگیره امکانش هست؟


+String.valueOf(str.charAt(m.start())) رو حذف کنید.

اون سایت هم تو پست شماره 6 همین تاپیک قدم به قدم توضیح دادم

----------


## shabgardetanha

> دیکشنری نیاز به فایلی دارید که اکثر کلمات انگلیسی رو داشته باشه. من چنین فایلی ندارم ولی در اینترنت هست و اونوقت بحث ساختمان داده و... هم مطرح میشه که در حالت ساده می تونید در HashMap ذخیره کنید و اونوقت برای پیدا کردنش مشکلات دیگه ای هم هست (چون مثلا heeellooo خودش میتونه چندین و چند حالت مختلف مثل heellooo hellooo helloo hello helo heelloo hو.... باشه) که کاریه که اینجا نمیشه صحبتش کرد و هر قسمت خودش بحث مفصلی ممکنه داشته باشه


سلام. خیلی ممنونم
ببخشید چه دیکشنری باید سرچ کنم؟

----------


## vahid-p

> سلام. خیلی ممنونم
> ببخشید چه دیکشنری باید سرچ کنم؟


اصطلاحا بهش میگیم دیکشنری. نه لزوما دیکشنری خاصی باشه.
 یه مخزنی برای کلمات هست. بلاخره کلمات خیلی زیادن و اینکه منبعش رو از کجا باید پیدا کنید نمیدونم.

----------


## shabgardetanha

سلام 
ممنون
یه سوال دیگه هم داشتم 
 این خط ها در جاوا چه معنایی داره؟


String[] words = content.split("\\(");
content = content.replaceAll("\\s+", " ");
	if(content.contains("data structure") && !content.trim().equals("data structure"))
			content = content.replaceAll("data structure", "");
و content.trim() یعنی چی؟
و من چطور میتونم به جای کاراکتر @,&.$ فاصله بنویسم؟ با کدهای بالا
و چطور به جای 'xv@کلمه'  (راست به چپ) میتونم بنویسم remove
و چطور کلمات یک جمله رو براساس فاصله بینشون بشکنم ؟ 
دوستان کسی میدونه؟
پیشاپیش ممنون

----------


## vahid-p

از داکیومنت جاوا استفاده کنید همش توضیح داده. اگر از IDE مثل netbeans و... استفاده میکنید موقع تایپ، جاواداکش هم میاد.
مثلا trim() فواصل اول و آخر یک رشته رو حذف میکنه.
split بر اساس regex یک رشته رو به رشته های دیگه میشکنه و به صورت آرایه بر میگردونه
در مورد بقیه سوالات نمونه هاییش رو تو پست های قبلی توضیح دادم، باید یادبگیرید تا بتونید برای نمونه های مشابه خودتون کد بزنید.




> و چطور کلمات یک جمله رو براساس فاصله بینشون بشکنم ؟


اگر split رو که گفتم رو یادبگیرید، پس میتونید برای این هم ازش استفاده کنید. پس اون سایتی که گفتم regexr.com رو استفاده کن برای تست regex و بعد در کد جاوا ازش استفاده کن.
\s یعنی فاصله (space, خط بعد و...) و \s+ یعنی بیشتر مساوی یک فاصله.
که کد جاواش میتونه این باشه:
String test = "This is  a  test";String[] arrStr = test.split("\\s+");
for(int i=0;i<arrStr.length;i++){
    System.out.println(arrStr[i]);
}

 اگر نتونستید هم در چنین مواقعی یه سرچ ساده جوابتون رو میده چون این دست سوالات به کررات مطرح شده و پاسخ داده شده. مثلا how to split a string by space in java
که اولین نتیجه ای که از گوگل بر میگرده جواب سوال شماست:
https://stackoverflow.com/questions/7899525

----------


## shabgardetanha

سلام


 ممنونم
بله حق با شماست سرچ کردم برای دو سوال 

و من چطور میتونم به جای کاراکتر @,&.$ فاصله بنویسم؟ با کدهای بالا
و چطور به جای 'xv@کلمه'  (راست به چپ) میتونم بنویسم remove
جوابی نگرفتم

ممنون میشم راهنمایی کنید
از اکیلیپش استفاده میکنم

----------


## shabgardetanha

سلام
برای حذف حروف اضافه این کد رو دیدم اما نمیدونم چطور ورودی بهش بدم(فایل تکست)
و دیکشنری چی میخواد؟
چطور توی این خط فایل ورودی متنی بدم؟
 BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));
ممنون میشم اگه کسی میدونه کمکم کنه؟
https://github.com/BbrianWwright/SampleCode/blob/master/SpellChecker.java

----------


## vahid-p

> و من چطور میتونم به جای کاراکتر @,&.$ فاصله بنویسم؟ با کدهای بالا


به نظرم سوالها داره تکرار میشه و همش یه چیزه فقط regex اش فرق میکنه. بهتره از رو یه آموزش regex رو یادبگیرید تا لااقل عبارت های ساده رو بتونید بنویسید.
مثلا اگر مثال های بالا رو مطالعه میکردید (نه استفاده) فکر میکنم میتونستید برای این سوالتون هم خودتون کدش رو بزنید و لااقل کدتون رو میذاشتید تا تلاش شما مشخص باشه و اینکه چرا جواب نمیگیرید. به هر حال من فقط regex چیزی که گفتید رو مینویسم:
[@,\,,&,.,$]+
طبق همون سایتی که گفتم میتونید تست کنید. کدش با خودتون. صد البته اگر نمیتونید از کدهای بالا استفاده کنید و تغییرات لازم رو اعمال کنید، به نظر من پایه های لازم رو نمیدونید و ابتدا باید مباحث پایه ای تر رو یادبگیرید و بعد به مباحث پیچیده تر برسید.

سوال بعد هم مشابهش پاسخ داده شده.




> از اکیلیپش استفاده میکنم


فرقی نمیکنه از چی استفاده کنید، همشون محیطی برای برنامه نویسی به زبان جاوا هستند.


به نظرم به سوال اصلی تاپیک پاسخ داده شده و میشه تاپیک رو "حل شده" دونست و بقیه سوالات (به خصوص پست آخر) هم خارج از بحث تاپیک هست.

----------


## shabgardetanha

چشم
ممنونم...
خیلی لطف کردید
اما جواب نداد
اینو هم برای $ نوشتم نشد
content = content.replaceAll("$", " ");

----------

