如何在JAVA中搜索阿拉伯语文本?
我在数据库中有带变音符号的阿拉伯文文本。当我键入阿拉伯语搜索某个字符串时,它没有与数据库字符串绝对不匹配的变音符号。它在没有变音符号的文本上工作得很好。有没有办法在带有变音符号的文本上运行它?阿拉伯变音符号是字符,所以您可以像这样使用like子句:如何在JAVA中搜索阿拉伯语文本?,java,android,arabic,text-search,Java,Android,Arabic,Text Search,我在数据库中有带变音符号的阿拉伯文文本。当我键入阿拉伯语搜索某个字符串时,它没有与数据库字符串绝对不匹配的变音符号。它在没有变音符号的文本上工作得很好。有没有办法在带有变音符号的文本上运行它?阿拉伯变音符号是字符,所以您可以像这样使用like子句: SELECT * FROM table WHERE name LIKE 'a[cd]*b[cd]*' 这将发现“ab”之间有任意数量的c或d 你可以在每个字母后面的方括号中加上所有阿拉伯字母的发音符号 您可以通过其unicode代码点找到所有这些代
SELECT * FROM table WHERE name LIKE 'a[cd]*b[cd]*'
这将发现“ab”之间有任意数量的c或d
你可以在每个字母后面的方括号中加上所有阿拉伯字母的发音符号
您可以通过其unicode代码点找到所有这些代码
有没有办法在带有变音符号的文本上运行它
不幸的是,没有。就像MIE说的:
阿拉伯文发音符号是字符 就我所知,这是不可能的 MIE的答案将很难实现,而且如果您更改数据库中的任何内容,将根本无法获得更新 你也许可以看看这个。我不确定,但看起来它能解决你的问题 或者,您需要从数据库中删除所有的变音符号,然后只需使用一个小型的阿拉伯语规范化器(如:
我发现这样做更好。所有奖励都是为了:
import java.text.Normalizer;
import java.text.Normalizer.Form;
/**
*
* @author Ibbtek <http://ibbtek.altervista.org/>
*/
public class ArabicDiacritics {
private String input;
private final String output;
/**
* ArabicDiacritics constructor
* @param input String
*/
public ArabicDiacritics(String input){
this.input=input;
this.output=normalize();
}
/**
* normalize Method
* @return String
*/
private String normalize(){
input = Normalizer.normalize(input, Form.NFKD)
.replaceAll("\\p{M}", "");
return input;
}
/**
* @return the output
*/
public String getOutput() {
return output;
}
public static void main(String[] args) {
String test = "كَلَّا لَا تُطِعْهُ وَاسْجُدْ وَاقْتَرِبْ ۩";
System.out.println("Before: "+test);
test=new ArabicDiacritics(test).getOutput();
System.out.println("After: "+test);
}
}
导入java.text.Normalizer;
导入java.text.Normalizer.Form;
/**
*
*@author Ibbtek
*/
公共类阿拉伯批评{
私有字符串输入;
私有最终字符串输出;
/**
*阿拉伯语系构造器
*@param输入字符串
*/
公共阿拉伯字母(字符串输入){
这个输入=输入;
this.output=normalize();
}
/**
*规范化方法
*@返回字符串
*/
私有字符串规范化(){
输入=Normalizer.normalize(输入,Form.NFKD)
.replaceAll(“\\p{M},”);
返回输入;
}
/**
*@返回输出
*/
公共字符串getOutput(){
返回输出;
}
公共静态void main(字符串[]args){
弦乐测试;
System.out.println(“之前:+测试);
test=新的ArabicDiacritics(test).getOutput();
System.out.println(“之后:”+测试);
}
}
请参见下面我为android创建的类,返回可扩展字符串。它是如此的基本,不需要担心内存消耗。你们可以优化自己
http://freshinfresh.com/sample/ABHArabicDiacritics.java
如果要检查阿拉伯字符串中包含的不带nunition(harakath)的内容
ABHArabicDiacritics objSearchd = new ABHArabicDiacritics();
objSearchdobjSearch.getDiacriticinsensitive("وَ اَشْهَدُ اَنْ لا اِلهَ اِلاَّ اللَّهُ").contains("اشهد");
如果要返回字符串中的高亮或红色搜索部分。
使用下面的代码
ABHArabicDiacritics objSearch = new ABHArabicDiacritics( وَ اَشْهَدُ اَنْ لا اِلهَ اِلاَّ اللَّهُ, اشهد);
SpannableString spoutput=objSearch.getSearchHighlightedSpan();
textView.setText(spoutput);
要查看搜索文本的开始和结束位置,
使用以下方法
/** to serch Contains */
objSearch.isContain();//
objSearch.getSearchHighlightedSpan();
objSearch.getSearchTextStartPosition();
objSearch.getSearchTextEndPosition();
请复制共享java类并享受
如果你们要求的话,我会花更多的时间来开发更多的功能
谢谢希望不要在聚会上迟到,我的问题与OP有点不同,我想搜索带有变音符号的阿拉伯语文本,并想用一些颜色标记搜索到的文本,因此我需要保存匹配文本的索引 问题是,规范化没有变音符号的文本将减少文本长度,并将获得搜索文本的不同索引 所以,通过使用正则表达式和
SpannableString
/*
* input: input text with Arabic Diacritics Or Letters that you want to ignore while searching
* searchedWord: the word/text that you want to search in @input text
* color: used to return a the founded matches with a different Foreground color using a SpannableString
* */
public static Spannable searchArabicWithIgnoredDiacriticsOrLetters(String input, String searchedWord, int color) {
Spannable output = new SpannableString(replaceLetters(input));
StringBuilder sb = new StringBuilder();
for (char ch : replaceLetters(searchedWord).toCharArray()) {
sb.append(ch);
sb.append("[\\u0655\\u0654\\u0670\\u065F\\u065E\\u065D\\u065C\\u065B\\u065A\\u0659\\u0658\\u0657\\u0656\\u06EC\\u06EB\\u06EA\\u06E4\\u061A\\u0619\\u0618\\u0617\\u0616\\u0615\\u064B\\u064C\\u064D\\u064E\\u064F\\u0650\\u0651\\u0652\\u0653\\u06DA\\u06D6\\u06D7\\u06D8\\u06D9\\u06DB\\u06DC\\u06DF\\u06E0\\u06E1\\u06E2\\u06E3\\u06E5\\u06E6\\u06E7\\u06E8\\u06EB\\u06EC\\u06ED]*");
}
Pattern pattern = Pattern.compile(String.valueOf(sb)); // get Pattern of the Regex
Matcher matcher = pattern.matcher(input); // get Matcher of the Pattern Regex in the input text
while (matcher.find())
output.setSpan(new ForegroundColorSpan(color),
matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return output;
}
public static String replaceLetters(String input) {
String output;
output = input.replaceAll("أ", "ا");
output = output.replaceAll("إ", "ا");
output = output.replaceAll("ى", "ي");
output = output.replaceAll("ة", "ه");
output = output.replaceAll("آ", "ا");
output = output.replaceAll("ٱ", "ا");
return output;
}
replaceLetters()
注意:您可以参考Unicode表示法的公认答案。文本的编码是什么?是utf-8吗?你是说你想搜索U+0632并找到U+0633吗?在这种情况下,您可以编写自己的搜索或字符串。replace()某些regexp In(使用regex搜索)是肯定的吗?您只需从db读取局部变量,并在局部删除变音符号,然后与搜索字符串进行比较。我用的是这种方式,它工作得很好。也许你应该放一个链接,指向这个答案的正确答案。谢谢你,这个程序真的很有用。测试字符串包含一个sajda-ayah。现在我需要做一个sajdah,只用于在Stackoverflow中阅读帖子。
String targetWord = "الذين"
String text = "صِرَاطَ الَّذِينَ أَنْعَمْتَ عَلَيْهِمْ غَيْرِ الْمَغْضُوبِ عَلَيْهِمْ وَلَا الضَّالِّين";
char[] input = targetWord.toCharArray();
StringBuilder regex = new StringBuilder("");
for(char c : input) {
regex.append(c);
regex.append("(\\p{M})*");
}
Pattern searchRegEx = Pattern.compile(regex.toString());
Matcher m = searchRegEx.matcher(text);
if(m.find()){
i = m.start();
System.out.println("m.group(0):: " + i + " : " + m.group(0));
}
/*
* input: input text with Arabic Diacritics Or Letters that you want to ignore while searching
* searchedWord: the word/text that you want to search in @input text
* color: used to return a the founded matches with a different Foreground color using a SpannableString
* */
public static Spannable searchArabicWithIgnoredDiacriticsOrLetters(String input, String searchedWord, int color) {
Spannable output = new SpannableString(replaceLetters(input));
StringBuilder sb = new StringBuilder();
for (char ch : replaceLetters(searchedWord).toCharArray()) {
sb.append(ch);
sb.append("[\\u0655\\u0654\\u0670\\u065F\\u065E\\u065D\\u065C\\u065B\\u065A\\u0659\\u0658\\u0657\\u0656\\u06EC\\u06EB\\u06EA\\u06E4\\u061A\\u0619\\u0618\\u0617\\u0616\\u0615\\u064B\\u064C\\u064D\\u064E\\u064F\\u0650\\u0651\\u0652\\u0653\\u06DA\\u06D6\\u06D7\\u06D8\\u06D9\\u06DB\\u06DC\\u06DF\\u06E0\\u06E1\\u06E2\\u06E3\\u06E5\\u06E6\\u06E7\\u06E8\\u06EB\\u06EC\\u06ED]*");
}
Pattern pattern = Pattern.compile(String.valueOf(sb)); // get Pattern of the Regex
Matcher matcher = pattern.matcher(input); // get Matcher of the Pattern Regex in the input text
while (matcher.find())
output.setSpan(new ForegroundColorSpan(color),
matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return output;
}
public static String replaceLetters(String input) {
String output;
output = input.replaceAll("أ", "ا");
output = output.replaceAll("إ", "ا");
output = output.replaceAll("ى", "ي");
output = output.replaceAll("ة", "ه");
output = output.replaceAll("آ", "ا");
output = output.replaceAll("ٱ", "ا");
return output;
}
public static String replaceLetters(String input) {
String output;
output = input.replaceAll("\\u0623", String.valueOf((char) Integer.parseInt("0627", 16))); // replace أ with ا
output = output.replaceAll("\\u0625", String.valueOf((char) Integer.parseInt("0627", 16))); // replace إ with ا
output = output.replaceAll("\\u0649", String.valueOf((char) Integer.parseInt("064A", 16))); // replace ي with ى
output = output.replaceAll("\\u0629", String.valueOf((char) Integer.parseInt("0647", 16))); // replace ة with ه
output = output.replaceAll("\\u0622", String.valueOf((char) Integer.parseInt("0627", 16))); // replace آ with ا
output = output.replaceAll("\\u0671", String.valueOf((char) Integer.parseInt("0627", 16))); // replace ٱ with ا
return output;
}