I have created an Android app wherein the users can give reviews and comments the products. Is there a way to control users from writing bad words in the reviews and comments or is there any sdk available for doing that.
You have to create a class for the censor module, this is somewhat greedy in implementation.
public class WordFilter {
static String[] words = {"bad", "words"};
public static String censor(String input) {
StringBuilder s = new StringBuilder(input);
for (int i = 0; i < input.length(); i++) {
for (String word : words) {
try {
if (input.substring(i, word.length()+i).equalsIgnoreCase(word)) {
for (int j = i; j < i + word.length(); j++) {
s.setCharAt(j, '*');
}
}
} catch (Exception e) {
}
}
}
return s.toString();
}
public static void main(String[] args) {
System.out.println(censor("String with bad words"));
}
}
Do it server side if you're using php and If you're just trying to do a simple word filter, create a single long regexp with all of the banned phrases that you want to censor, and merely do a regex find/replace with it. A regex like:
$filterRegex = "(boogers|snot|poop|shucks|argh|fudgecicles)"
and run it on your input string using preg_match() to wholesale test for a hit,
or preg_replace() to blank them out.
Related
I am stuck with the ObjectBox Like Query. I have done as below when I search for something.
QueryBuilder<MItemDetail> builder = mItemDetailListBox.query();
builder.contains(MItemDetail_.productName, search);
itemList = builder.build().find();
For example, My data is:
paracetamol
paracetamol potest
paracetamol_new
Problem:
Now as you know the contains works simply as that returns a list of items that contain a given search string.
What I Want:
If I search para new, I want the result paracetamol_new
If I search para p, I want the result paracetamol potest
If I search para e e, I want the result paracetamol potest and paracetamol_new
Is there any function or utility available in ObjectBox that can help me to achieve this?
Do let me know If you have any questions.
Edited:
The given links in a comment, My question is different. I know all the methods contains(), startsWith, and endsWith but my problem not getting solved using that.
With Reference to this answer I have done some changes as given and I got a perfect solution as I wanted.
QueryBuilder<MItemDetail> builder = mItemDetailListBox.query();
// builder.contains(MItemDetail_.productName, search);
builder.filter(new QueryFilter<MItemDetail>() {
#Override
public boolean keep(#NonNull MItemDetail entity) {
return like(entity.getProductName(), "%"+ search + "%");
}
}).order(MItemDetail_.productName);
businessModels = builder.build().find();
In the following methods, I have added one more replace statement .replace(" ",".*?")
private static boolean like(final String str, final String expr) {
String safeString = (str == null) ? "" : str;
String regex = quoteMeta(expr);
regex = regex.replace("_", ".").replace(" ",".*?").replace("%", ".*?");
Pattern p = Pattern.compile(regex,
Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
return p.matcher(safeString).matches();
}
private static String quoteMeta(String s) {
if (s == null) {
throw new IllegalArgumentException("String cannot be null");
}
int len = s.length();
if (len == 0) {
return "";
}
StringBuilder sb = new StringBuilder(len * 2);
for (int i = 0; i < len; i++) {
char c = s.charAt(i);
if ("[](){}.*+?$^|#\\".indexOf(c) != -1) {
sb.append("\\");
}
sb.append(c);
}
return sb.toString();
}
Thank you.
I was looking for an example and alive code to transfer just a list of objects into Json string and vice versa.
It is not a secret, that Androids are often used as a communication devices between (in my case) PC with .NET and the Android device itself.
The very common operation is to send SMS messages to a group of subscribers, that's usually exists as a List of objects.. say..
class Man {
public string Number {get;set;}
public string Message {get;set;}
}
So, the List<Man> Men = new List<Man>();
is quite intuitive as the basic structure.
I can convert both ways in C#.NET
using System;
using Newtonsoft.Json;
using System.Collections.Generic;
public class Program
{
public static void Main() {
List<Man> Men = new List<Man>();
// numbers are just random
Man m1 = new Man();
m1.Number = "+6149168158";
m1.Message = "Hello Bob from 1";
m1.UniqueCode = "0123";
m1.State = 0;
Man m2 = new Man();
m2.Number = "+6146146182";
m2.Message = "Hello Bob from 2";
m2.UniqueCode = "0125";
m2.State = 0;
Men.AddRange(new Man[] { m1, m2 });
string result = JsonConvert.SerializeObject(Men);
Console.WriteLine(result);
List<Man> men = JsonConvert.DeserializeObject<List<Man»(result);
foreach(Man m in men) Console.WriteLine(m.Message);
}
}
public class Man
{
public string Number{get;set;}
public string Message {get;set;}
public string UniqueCode {get;set;}
public int State {get;set;}
}
It works.. but the Android side.. just like a dark matter.. I am sure it exists, but I can't touch it..
So, please, whoever knows it, please, publish the Android part here, so the others would get nice and clear example for such a standard requirement.
(No Gson, Mason or some others.. only Android and only JSON..
Thank you..
It looks like you might not want to use the tools available( Gson, Mason or some others..)
You must manually implement your mapper class for every object:
Native tools for android are JSONArray,JSONObject;
In the following code I have provided an example of decoding
Ok, this is the Deserializator
public List<Man> DecodeFactor(String json) throws JSONException {
List<Man> list = null;
try
{
JSONArray headarrays=new JSONArray(json);
if(headarrays.length()>0)
{
list=new ArrayList<Man>();
for (int i = 0; i <headarrays.length() ; i++)
{
Man man=new Man();
JSONObject o = headarrays.getJSONObject(i);
man.Message = o.getString("Message");
man.Number = o.getString("Number");
man.UniqueCode = o.getString("UniqueCode");
man.State = o.getInt("State");
list.add(man);
}
}
}catch (Exception ee) { ee.printStackTrace(); }
return list;
}
I want to develop pattern searching algorithm for an music system application which searches for given keyword and plays the music whose text file contains the given keyword. Now there are many pattern searching algorithm which can do this efficiently(ex: KMP, hashing(may give error) etc). But my main problem is that the whole database is in language other than english( "Hindi" to be specific). Now the user enters the given keyword in "Hindi" language and I want to search in the database that also contains "Hindi" language. My main concern is that how to efficiently search in this database?
I think that we can't do KMP algorithm for non-english language because ascii charaters that we use only contains english alphabets and other numeric letters but doesn't contains letters of other language. So,please tell me how can I proceed further as I am not able to get solution or tell where I am thinking in wrong way?
KMP algorithm don't base on alphabet, it uses characters from given pattern and text. Moreover in languages like Java, strings use UTF-8 encoding, so u can use any langague you like and algorithm will work properly, in others you need to choose encoding explicitly. Here I give link to example on Ideone of using KMP with non ascii charset.
KMP algorithm
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone {
int[] f;
public void dfa(String pattern) {
int m = pattern.length();
f = new int[m+1];
f[0] = 0;
f[1] = 0;
for(int i=2; i<=m; i++) {
int j = f[i-1];
for(;;) {
if(pattern.charAt(j) == pattern.charAt(i-1)) {
f[i] = j +1;
break;
}
if(j==0) {
f[i] = 0;
break;
}
j = f[j];
}
}
}
public int match(String text, String pattern) {
dfa(pattern);
int n = text.length();
int m = pattern.length();
int i = 0;
int j = 0;
for(;;) {
if(i == n) break;
if(text.charAt(i) == pattern.charAt(j)) {
j++;
i++;
if(j == m) return i;
}
else if(j > 0) j =f[j];
else i++;
}
return -1;
}
public static void main(String[] args) {
Ideone kmp = new Ideone();
String text = "AĄĘĆABA";
String pattern = "ĄĘĆ";
System.out.println(kmp.match(text, pattern));
}
}
I am trying to save the state in my Fragment through the use of Parcelable.
This lead to the following code when I wish to get back the a String array that I saved in the Parcelable:
public MyObject createFromParcel(Parcel in) {
titles=in.readStringArray(???);
}
Now readStringArray needs a parameter, a String[]... But why? It could just give the Strings that I stored in it. I don't know a priori how many there were, so this sucks. :(
The documentation says the following:
That is, nothing.
EDIT: If anyone has the same problem: I ended up using writeBundle()/readBundle() and putting my String[] into the Bundle.
Use createStringArray() instead of readStringArray(String[]). It will return the array you need.
Here is an implementation of this method from Android 4.1.2:
public final void readStringArray(String[] val) {
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
val[i] = readString();
}
} else {
throw new RuntimeException("bad array lengths");
}
}
So it writes values to given array. And returns nothing.
I think it might be useful to view these two methods, readStringArray(String[] val) and createStringArray() side by side:
Let's look at readStringArray(String[] val) method first. It requires a String[] as a parameter and might result in a NullPointerException if you pass a non-initialised array object (null). Also, you'll have to know exactly the length of the array (N), otherwise you'll get the RuntimeException thrown from the method:
public final void readStringArray(String[] val) {
int N = readInt();
if (N == val.length) {
for (int i=0; i<N; i++) {
val[i] = readString();
}
} else {
throw new RuntimeException("bad array lengths");
}
}
Oh the other hand, with createStringArray() you don't need to form and provide a String[] as a parameter, it will be formed for you by the method with the correct length too, so you don't have to worry about either NullPointerException or RuntimeException:
public final String[] createStringArray() {
int N = readInt();
if (N >= 0) {
String[] val = new String[N];
for (int i=0; i<N; i++) {
val[i] = readString();
}
return val;
} else {
return null;
}
}
All in all, as a result of this basic analysis we can jump to conclusions and say that the second method is better and safer..
What I want to do...
I have a webview in my android app. I get a huge html content from the server as a string and a search string from the application user(the android phone user). Now I break the search string and create a regex out of it. I want all the html content that matches my regex to be highlighted when I display it into my WebView.
What I tried...
Since it is html, I just want to wrap the regex matched words into a pair of tags with yellow background.
Simple regex and replaceAll on the html Content that i get. Very wrong because it screws and replaces even what is inside the '<' and '>'.
I tried using Matcher and Pattern combo. It is difficult to omit what is inside the tags.
I used JSOUP Parser and it worked!
I traverse the html using NodeTraversor class. I used Matcher and Pattern classes to find and replace matched words with tags as i wanted to do.
But it is very slow. And I basically want to use it on Android and the size of it is like 284kB. I removed some unwanted classes and it is now 201kB but it is still too much for an android device. Additionally, the html content can be really large. I looked into JSoup source as well. It kind of iterates over every single character when it parses. I do not know whether all the parsers do the same but it is definitely slow for large html documents.
Here is my code -
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Highlighter {
private String regex;
private String htmlContent;
Pattern pat;
Matcher mat;
public Highlighter(String searchString, String htmlString) {
regex = buildRegexFromQuery(searchString);
htmlContent = htmlString;
pat = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
}
public String getHighlightedHtml() {
Document doc = Jsoup.parse(htmlContent);
final List<TextNode> nodesToChange = new ArrayList<TextNode>();
NodeTraversor nd = new NodeTraversor(new NodeVisitor() {
#Override
public void tail(Node node, int depth) {
if (node instanceof TextNode) {
TextNode textNode = (TextNode) node;
String text = textNode.getWholeText();
mat = pat.matcher(text);
if(mat.find()) {
nodesToChange.add(textNode);
}
}
}
#Override
public void head(Node node, int depth) {
}
});
nd.traverse(doc.body());
for (TextNode textNode : nodesToChange) {
Node newNode = buildElementForText(textNode);
textNode.replaceWith(newNode);
}
return doc.toString();
}
private static String buildRegexFromQuery(String queryString) {
String regex = "";
String queryToConvert = queryString;
/* Clean up query */
queryToConvert = queryToConvert.replaceAll("[\\p{Punct}]*", " ");
queryToConvert = queryToConvert.replaceAll("[\\s]*", " ");
String[] regexArray = queryString.split(" ");
regex = "(";
for(int i = 0; i < regexArray.length - 1; i++) {
String item = regexArray[i];
regex += "(\\b)" + item + "(\\b)|";
}
regex += "(\\b)" + regexArray[regexArray.length - 1] + "[a-zA-Z0-9]*?(\\b))";
return regex;
}
private Node buildElementForText(TextNode textNode) {
String text = textNode.getWholeText().trim();
ArrayList<MatchedWord> matchedWordSet = new ArrayList<MatchedWord>();
mat = pat.matcher(text);
while(mat.find()) {
matchedWordSet.add(new MatchedWord(mat.start(), mat.end()));
}
StringBuffer newText = new StringBuffer(text);
for(int i = matchedWordSet.size() - 1; i >= 0; i-- ) {
String wordToReplace = newText.substring(matchedWordSet.get(i).start, matchedWordSet.get(i).end);
wordToReplace = "<b>" + wordToReplace+ "</b>";
newText = newText.replace(matchedWordSet.get(i).start, matchedWordSet.get(i).end, wordToReplace);
}
return new DataNode(newText.toString(), textNode.baseUri());
}
class MatchedWord {
public int start;
public int end;
public MatchedWord(int start, int end) {
this.start = start;
this.end = end;
}
}
}
Here is how I call it -
htmlString = getHtmlFromServer();
Highlighter hl = new Highlighter("Hello World!", htmlString);
new htmlString = hl.getHighlightedHTML();
I am sure what i'm doing is not the most optimal way. But I can't seem to think of anything else.
I want to
- reduce the time it takes to highlight it.
- reduce the size of library
Any suggestions?
How about highlighting them using javascript?
You know, everybody love javascript, and you can find example like this blog.
JTidy and HTMLCleaner are aloso among the best Java HTML Parser.
see
Comparison between different Java HTML Parser
and
What are the pros and cons of the leading Java HTML parsers?