Evaluating String in java Using ScriptEnging - java

Below is my code to take a somewhat simple user input of hello or mouse and search a String(I will later use this on much larger text files).
I use it to create a Java line of code that uses the contains method. After, I need to evaluate it. I found some help using the Script engine, but I keep getting this error: Exception in thread "main" javax.script.ScriptException: ReferenceError: "name" is not defined in <eval> at line number 1 The output that comes from the code that I want to evaluate is name.contains("hello") || name.contains("mouse").
Any help would be great. Thanks
public static void main(String args[]) throws ScriptException {
String searchString = "name";
String terms = "(hello) || (mouse)";
String command = "";
//multiple commands
if(terms.contains("(") && terms.contains(")") && terms.contains("[") && terms.contains("]")){
command = terms.replace(")","\")");
command=command.replace("(", searchString + ".contains(\"");
command = command.replace("[","(");
command = command.replace("]",")");
}
//only ands/ only ors
else {
command = terms.replace("(", searchString + ".contains(\"");
command = command.replace(")", "\")");
}
System.out.println(command);
String name = "mousehellonamepe";
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval(command);
System.out.println(result);

What are you trying to do exactly ?
======= Update ======
First, String terms should be a list.
Make it:
ArrayList<String> searchTerms = new ArrayList();
Add as many words as you like to that list as follows:
// using add() to initialize values
arr.add("Hello");
arr.add("Mouse");
arr.add("Bike");
arr.add("House");
// use contains() to check if the element
// 2 exits or not
boolean mouseExists = arr.contains("Mouse");
if (ans)
System.out.println("Our list contains the word mouse");
else
System.out.println("Our list does not contain the word mouse");
This should output this:
Our list contains the word mouse
Code should look like this:
public static void main(String args[]) throws ScriptException {
ArrayList<String> searchTerms = new ArrayList();
arr.add("Hello");
arr.add("Mouse");
arr.add("Bike");
arr.add("House");
boolean mouseExists = arr.contains("Mouse");
if (ans)
System.out.println("Our list contains the word mouse");
else
System.out.println("Our list does not contain the word mouse");
}

Interpreter i = new Interpreter();
i.set("searchThis", searchString);
i.set("answer", i.eval(command));
Boolean answer2 = (Boolean) (i.get("answer"));
http://www.beanshell.org/manual/quickstart.html#Calling_BeanShell_From_Your_Application
I used this to evaluate the command.
the link above provides all the explanation!

Related

How to get the field name of a primitive object inspector in java

I am trying to solve this problem for an UDF I am creating for hiveql environment.
public ObjectInspector initialize(ObjectInspector[] arguments)
throws UDFArgumentException {
if (arguments.length != 1) {
throw new UDFArgumentException("Usage : multiple_prop(primitive var) ");
}
// This will be an string
moi = (PrimitiveObjectInspector) arguments[0];
ArrayList structFieldNames = new ArrayList();
ArrayList structFieldObjectInspectors = new ArrayList();
structFieldNames.add("fields name"); <-- Issue is here
How could I do to get the field name in there? It can be easily done for structObjectInspectors, but how do we manage this in PrimitiveObjectInspectors?
Complete code would be this one
public class prop_step2 extends GenericUDF {
private PrimitiveObjectInspector moi;
#Override
public ObjectInspector initialize(ObjectInspector[] arguments)
throws UDFArgumentException {
if (arguments.length != 1) {
throw new UDFArgumentException("Usage : multiple_prop(primitive var) ");
}
// This will be an string
moi = (PrimitiveObjectInspector) arguments[0];
ArrayList structFieldNames = new ArrayList();
ArrayList structFieldObjectInspectors = new ArrayList();
// Change this to get the input variable name, and not the type name
structFieldNames.add(moi.getTypeName());<-- Change this to field name
structFieldObjectInspectors.add( PrimitiveObjectInspectorFactory.writableStringObjectInspector );
return ObjectInspectorFactory.getStandardStructObjectInspector(structFieldNames, structFieldObjectInspectors);
}
#Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
Object[] result;
result = new Object[1];
Text elem1 = new Text((String) moi.getPrimitiveJavaObject(arguments[0].get()));
result[0]= elem1;
return result;
}
#Override
public String getDisplayString(String[] children) {
return "stop";
}}
When this would be finished, i would like to call this udf from hive:
CREATE TEMPORARY FUNCTION step AS 'UDFpack.prop_step2';
select
step(bit) as sd
from my_table
And i would expect that if in an upper select i did this : sd.bit i would obtain the value of 'bit'.
It's simply not possible. The information passed to the UDF - the ObjectInspectors - do not contain their name. That's why you can see the output column names being changed to _col0, _col1 .. in the intermediary stages of a Hive explain plan. I am also quite annoyed by this and think this is an oversight by Hive.
A workaround would be to put your input into a struct and parse that.
i.e step(named_struct('bit',bit)) and then you can get the field name of the struct in your UDF. But it's not nearly as nice

Common Hypernym between two words using WordNet (JWI) - JAVA

Does anyone know how a good way to retrieve the first common hypernym between two words? I can access the first level (immediate parent) from a given word, but I'm stuck on how to retrieve all hypernyms ("going up") from this word until it matches another word. The idea is to identify where/when/which two words can be considered "the same" through WordNet according with their root (if not found it should continue until the end of the words in wordnet). I found some topics here but for Python and Perl, nothing specific for this problem in JAVA
I'm using JWI (2.4.0) to access SynsetID, WordID and other information from WordNet. If there is a simpler API that does the job is also welcome. Here below is the method that provides the hypernym I mentioned.
public void getHypernyms(IDictionary dict_param, String lemma_param) throws IOException {
dict_param.open();
// get the synset
IIndexWord idxWord = dict_param.getIndexWord(lemma_param, POS.NOUN);
// 1st meaning
IWordID wordIDb = idxWord.getWordIDs().get(0);
IWord word = dict_param.getWord(wordIDb);
ISynset synset = word.getSynset();
System.out.println("Synset = " + synset);
// get the hypernyms by pointing a list of <types> in the words
List<ISynsetID> hypernyms = synset.getRelatedSynsets(Pointer.HYPERNYM);
// print out each h y p e r n y m s id and synonyms
List<IWord> words, wordsb;
for (ISynsetID sid : hypernyms) {
words = dict_param.getSynset(sid).getWords();
System.out.println("Lemma: " + word.getLemma());
System.out.print("Hypernonyms = " + sid + " {");
for (Iterator<IWord> i = words.iterator(); i.hasNext();) {
System.out.print(i.next().getLemma());
if (i.hasNext()) {
System.out.print(", ");
}
}
System.out.println("}");
}
}
Providing a dictionary and the word "dog" we have as a result (as you can see I'm just usingn the first meaning to execute this method):
Synset = SYNSET{SID-02084071-N : Words[W-02084071-N-1-dog, W-02084071-N-2 domestic_dog, W-02084071-N-3-Canis_familiaris]}
Lemma: dog Hypernonyms = SID-02083346-N {canine, canid}
Lemma: dog Hypernonyms = SID-01317541-N {domestic_animal, domesticated_animal}
For those who might be interested. After some time I figured it out.
public List<ISynsetID> getListHypernym(ISynsetID sid_pa) throws IOException {
IDictionary dict = openDictionary();
dict.open(); //Open the dictionary to start looking for LEMMA
List<ISynsetID> hypernym_list = new ArrayList<>();
boolean end = false;
while (!end) {
hypernym_list.add(sid_pa);
List<ISynsetID> hypernym_tmp = dict.getSynset(sid_pa).getRelatedSynsets(Pointer.HYPERNYM);
if (hypernym_tmp.isEmpty()) {
end = true;
} else {
sid_pa = hypernym_tmp.get(0);//we will stick with the first hypernym
}
}
//for(int i =0; i< hypernym_list.size();i++){
// System.out.println(hypernym_list.get(i));
//}
return hyp;
}

Find and Delete a Sub-String in Java

I'm trying to find a Java sub-string and then delete it without deleting the rest of the string.
I am taking XML as input and would like to delete a deprecated tag, so for instance:
public class whatever {
public static void main(String[] args) {
String uploadedXML = "<someStuff>Bats!</someStuff> <name></name>";
CharSequence deleteRaise = "<name>";
// If an Addenda exists we continue with the process
if (xml_in.contains(deleteRaise)){
// delete
} else {
// Carry on
}
}
In there I would like to delete the <name> and </name> tags if they are included in the string while leaving <someStuff> and </someStuff>.
I already parsed the XML to a String so there's no problem there. I need to know how to find the specific strings and delete them.
You can use replaceAll(regex, str) to do this. If you're not familiar with regex, the ? just means there can be 0 or 1 occurrences of / in the string, so it covers <name> and </name>
String uploadedXML = "<someStuff>Bats!</someStuff> <name></name>";
String filter = "</?name>";
uploadedXML = uploadedXML.replaceAll(filter, "");
System.out.println(uploadedXML);
<someStuff>Bats!</someStuff>
String uploadedXML = "<someStuff>Bats!</someStuff> <name></name>";
String deleteRaise = "<name>";
String closeName = "</name>"
// If an Addenda exists we continue with the process
if (xml_in.contains(deleteRaise)){
uploadedXML.replace(uploadedXML.substring(uploadedXML.indexOf(deleteRaise),uploadedXML.indexOf(closeName)+1),"");
} else {
// Carry on
}enter code here

How to replace words with Parallel arrays

Hello i am new to this forum. I am fairly new to Java. I am trying to convert USA to UK words so that when i input a sentence containing any of the USA words, the output will be will be the sentence but replaced with UK words. This is my attempt:
import javax.swing.JOptionPane;
public class PArraystest
{
public static void main(String [] arg)
{
String[] wordUSA = {"Cell", "Elevator", "Fries", "Gasoline", "Faucet"};
String[] wordUK = {"Mobile", "Lift", "Chips", "Petrol", "Tap"};
String changeUK = "";
String sent;
sent = JOptionPane.showInputDialog("What name do you want to search for?");
for (int i = 0; i < wordUSA.length; i++)
{
if (sent.contains(wordUSA[i]))
{
sent.replace((wordUK)[i],(wordUSA)[i]);
//break;
}
}
//if (changeUK.equals(""))
//System.out.println(" was not found.");
//else
System.out.println(sent);
}
}
Two things:
You need to use assign the string returned from replace to sent again, or sent will be unchanged`.
The replace method is public String replace(char oldChar, char newChar), so the oldChar US word should come first, followed by the UK word.
This is the correct line: sent = sent.replace(wordUSA[i],wordUK[i]);
The replace method returns a new String with the replaced text:
//sent.replace((wordUK)[i],(wordUSA)[i]);
sent = sent.replace((wordUK)[i],(wordUSA)[i]);
Two problems:
First, you should assign the replaced string back to sent.
Second, you should use replaceAll instead of replace.
There's a whole framework of functionality devoted to this in Java called internationalizaion (i18n)
While the sample below is primarily for generation origianlly I thought I'd point it out because you could probably devise how to run it in reverse as well.
Here's a snippet that shows the proper way to go about this:
http://docs.oracle.com/javase/tutorial/i18n/intro/after.html
(all code below is theirs and not my own)
Note that to run this you'll need the resource files from the site or the versions I have provided below from the site
import java.util.*;
public class I18NSample {
static public void main(String[] args) {
String language;
String country;
if (args.length != 2) {
language = new String("en");
country = new String("US");
} else {
language = new String(args[0]);
country = new String(args[1]);
}
Locale currentLocale;
ResourceBundle messages;
currentLocale = new Locale(language, country);
messages = ResourceBundle.getBundle("MessagesBundle", currentLocale);
System.out.println(messages.getString("greetings"));
System.out.println(messages.getString("inquiry"));
System.out.println(messages.getString("farewell"));
}
}
MessagesBundle.properties:
greetings = Hello.
farewell = Goodbye.
inquiry = How are you?
MessagesBundle_en_US.properties:
greetings = Hello.
farewell = Goodbye.
inquiry = How are you?
MessagesBundle_fr_FR.properties:
greetings = Bonjour.
farewell = Au revoir.
inquiry = Comment allez-vous?

Refactor this Java code checking if a String contains any of these possibilities?

I am needing to check if a string does NOT contain any of these string possibilities:
MNC
BRA
LEB
MAR
RVC
WAY
GLZ
WWW
HYB
My current code :
if(selectedLocation.equals("OTH"))
{
if(!currentClassLocation.equals("MNC") &&
!currentClassLocation.equals("BRA") &&
!currentClassLocation.equals("LEB") &&
!currentClassLocation.equals("MAR") &&
!currentClassLocation.equals("RVC") &&
!currentClassLocation.equals("WAY") &&
!currentClassLocation.equals("GLZ") &&
!currentClassLocation.equals("WWW") &&
!currentClassLocation.equals("HYB"))
{
//Awesome, I need this string! I operate on it here.
}
}
Long story short, I can't use a for-loop. Is there a way I can check if the string doesn't contain any of these without iteration?
Use a HashSet:
Set<String> invalidSequences = new HashSet<String>();
invalidSequences.add("MNC");
invalidSequences.add("BRA");
invalidSequences.add("LEB");
// Remaining sequences ...
if (!invalidSequences.contains(currentClassLocation)) {
// Awesome, I need this string...
}
Try adding those strings to Set then look up using contains which will be O(c):
public class Filter {
Set<String> exclusionSet = new HashSet<String>();
public Filter( String... excludes ) {
for( String exclusion : excludes ) {
exclusionSet.add( exclusion );
}
}
public boolean exclude( String src ) {
return exclusionSet.contains( src );
}
public static void main( String[] args ) {
Filter filter = new Filter( "MNC BRA LEB MAR RVC WAY GLZ WWW HYB".split(" ") );
for( String arg : args ) {
System.out.println( arg + " is excluded? " + filter.exclude( arg ) );
}
}
}
Make a HashSet of your strings, and do a O(1) check to see if the current class location exists in your set of strings.
Try a variation (using your strings) of this:
Pattern pattern = Pattern.compile("(.*(AIN|BIN|CIN|Blam).*)*");
Matcher matcher = pattern.matcher(string_to_test);
Test java regex patterns here: Java Regex Tester
If you want to use a for-loop you could simply use a variable
String[] data = {"BRA","LEB","MAR","RVC","WAY","GLZ","WWW","HYB"};
if(selectedLocation.equals("OTH"))
{
boolean chk = false;
for(int i = 0; i < data.length; i++)
chk |= currentClassLocation.equals(data[i]);
if(!chk){
//Awesome, I need this string! I operate on it here.
}
}
You can also use this if you don't want to manually add the data to set.
import java.util.Arrays;
public class StringFind {
public static void main(String[] args) {
String stringtotest = "MNC";
String dataString = "MNC BRA LEB MAR RVC WAY GLZ WWW HYB";
String[] dataArray= dataString.split(" ");
Arrays.sort(dataArray); // You can omit this if data is already sorted.
if(Arrays.binarySearch(dataArray, stringtotest)<0){
System.out.println("Does not Exists");
}else{
System.out.println("Exists");
}
}
}
Use a config file so that the list of invalid sequences becomes configurable. For this is the smelliest bit, the series of magic letter combinations. Moving it to a set does not help with that.
Using a string array:
String[] arr = {"MNC", "BRA", "LEB", "MAR", "RVC", "WAY", "GLZ", "WWW", "HYB"};
List list = Arrays.asList(arr);
if (!list.contains(currentClassLocation)) {
...
}

Categories

Resources