Extracting Phone Number with Call Text from String using Reg exp - java

Ok Here is my example text... everything is
THEPONDIS15AWAYLOOKATTHOSEBASS5POUNDERSWELLLITATNIGHTALLAROUNDQUIETSEMICOUNTRYAREASTILLMOREBUTCALLMENORENTALNOLEASEANDPLEASEWENEEDNOREALTORSASMYWIFEDOES3176665440ANDCANNOTKEEPALLTHEMAINTANCEOFABIGHOUSEWANNAGOSOUTHTHANKSCALLMETHANKS
As you can see the Call and the phone number are within so far of eachother within 60 chars or so. So I been trying to right an expression to find this, determine that CALL is within 60 chars or so and then pull the phone number if it is..
I know that I would need something like...
Pattern p11 = Pattern.compile("[0-9]{11}");
Pattern p10 = Pattern.compile("[0-9]{10}");
Pattern p7 = Pattern.compile("[0-9]{7}");
In order to determine if its possibly an actual phone number since it could be 13173333333 or just 3173333333 or just 3333333
What about the rest? I know I would probably have to do a type of substring or something, but Its giving me a lot more difficulty then I thought it would.
I tried doing this...
String PHONENUMBER = "";
Pattern p11 = Pattern.compile("[0-9]{11}");
Pattern p10 = Pattern.compile("[0-9]{10}");
Pattern p7 = Pattern.compile("[0-9]{7}");
Matcher m11 = p11.matcher(Number);
Matcher m10 = p10.matcher(Number);
Matcher m7 = p7.matcher(Number);
String Call = "CALL";
String Text = "TEXT";
String Message = "MESSAGE";
if (Number.contains(Call)) {
int Numindex = Number.indexOf(Call);
int low = Numindex - 30;
int high = Numindex + 35;
if (low < 0) {
low = 0;
}
if (high > Number.length()) {
high = Number.length();
}
String extract = Number.substring(low, high);
m11 = p11.matcher(extract);
m10 = p10.matcher(extract);
m7 = p7.matcher(extract);
if (m11.find() == true) {
PHONENUMBER = m11.group();
} else if (m10.find() == true) {
PHONENUMBER = m10.group();
} else if (m7.find() == true) {
PHONENUMBER = m7.group();
}
But for some reason its not working out for me
EDIT #1 Requested for Original Text....
The Pond is 15' away- look at those bass- 5 Pounders-- well lit at night all around- quiet Semi Country area...still more but Ca ll me- NO RENTAL/No Lease and Please- we need NO Realtors as my Wife does 317 6 6.6-54.4 0 and cannot keep all the maintance of a big House- wanna go South Thanks call me!Call Me Thanks!
As you can see from the original text, it only makes sense to remove the spaces and all special characters then just do a simple expression comparison to find the phone number, then just find if the word "call" is within 60 chars. Obviously this isn't the ONLY paragraph there are hundreds more.

I'll be honest this seems like you are doing it in an extremely difficult way. However here is an idea on how you could go about doing it.
First get the range you want to check for the number let's say it's 0(low)-15(high)
then write a for loop to loop through that range of characters. The below code is an example of how you could set it up to loop through the section of the string you want checking the characters along the way to see if it matches a phone number. Take in mind this doesn't take in account reaching the end of the String to soon which would result in an index out of bounds exception nor does it take in account if it is too large of a number but I will let you figure those things out.
String number = "123HEY1234567890HOWIS";
int realNum = 0; //if this hits exactly 10 then it is a real phone number
int low = 0;
int high = number.length();
for(int i = low; i < high;i++){
//check if the current char is a number
if(number.substring(i, i + 1).matches("[0-9]")){
//if yes then increment
realNum++;
System.out.println(realNum);
//checks if realNum is 10 and makes sure that the next char isn't a number also
if(realNum == 10){
low = i - 9;
high = i;
System.out.println("match");
break;
}
}else{
//if no then reset the checker back to 1
realNum = 0;
}
}
System.out.println("All Done");
Hopefully this at least gets you on the right path.

I would use https://github.com/googlei18n/libphonenumber and not regex for finding phone numbers. The library works as you would expect
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Iterable<PhoneNumberMatch> numbers = phoneUtil.findNumbers(text, Locale.US.getCountry());
List<String> data = new ArrayList<>();
numbers.forEach(number -> {
String s = number.rawString();
// your phone numbers
});

Related

Expand the range of numbers

I was trying a solve a issue which is bothering me for a while. I created a small parser that reads an .ini file and then stores the data in an ArrayList. However, I got stuck with the following snippet:
while (!(sCurrentLine.equals("[End]"))) {
formats.add(sCurrentLine);
for (int i = 0; formats.size() > 0; i++) {
}
sCurrentLine = br.readLine();
}
Now this is the place where I have to add values into formats, which is of type ArrayList.
The values that will be added like this:
0900.013-017=LABEL
0900.018-029=LABEL
Now the range is in between and I also have to make sure that '0900' and '=label' repeats themselves along with the expansion of numbers, for example:
0900.013=LABEL
0900.014=LABEL
0900.015=LABEL
0900.016=LABEL and so on...
and store it back in the ArrayList.
I don't want to depend upon third-party libraries. Please help me out with this.
Use a regular expression to parse the range, then loop over the parsed values. There is some fine tuning to be done but I think this should get you started.
Pattern rangePattern = Pattern.compile("([0-9]+)\\.([0-9]+)-([0-9]+)=(.*)$");
Matcher rangeMatcher = rangePattern.matcher("0900.13-17=First label");
if (rangeMatcher.matches()) {
String prefix = rangeMatcher.group(1);
int start = Integer.parseInt(rangeMatcher.group(2));
int end = Integer.parseInt(rangeMatcher.group(3));
String label = rangeMatcher.group(4);
for (int r = start; r < end; r++) {
System.out.println(prefix + "." + r + "=" + label);
}
}
Create the pattern once and then just get new matchers each time through your loop.
The results:
0900.13=First label
0900.14=First label
0900.15=First label
0900.16=First label

Find all valid words when given a string of characters (Recursion / Binary Search)

I'd like some feedback on a method I tried to implement that isn't working 100%. I'm making an Android app for practice where the user is given 20 random letters. The user then uses these letters to make a word of whatever size. It then checks a dictionary to see if it is a valid English word.
The part that's giving me trouble is with showing a "hint". If the user is stuck, I want to display the possible words that can be made. I initially thought recursion. However, with 20 letters this can take quite a long time to execute. So, I also implemented a binary search to check if the current recursion path is a a prefix to anything in the dictionary. I do get valid hints to be output however it's not returning all possible words. Do I have a mistake here in my recursion thinking? Also, is there a recommended, faster algorithm? I've seen a method in which you check each word in a dictionary and see if the characters can make each word. However, I'd like to know how effective my method is vs. that one.
private static void getAllWords(String letterPool, String currWord) {
//Add to possibleWords when valid word
if (letterPool.equals("")) {
//System.out.println("");
} else if(currWord.equals("")){
for (int i = 0; i < letterPool.length(); i++) {
String curr = letterPool.substring(i, i+1);
String newLetterPool = (letterPool.substring(0, i) + letterPool.substring(i+1));
if(dict.contains(curr)){
possibleWords.add(curr);
}
boolean prefixInDic = binarySearch(curr);
if( !prefixInDic ){
break;
} else {
getAllWords(newLetterPool, curr);
}
}
} else {
//Every time we add a letter to currWord, delete from letterPool
//Attach new letter to curr and then check if in dict
for(int i=0; i<letterPool.length(); i++){
String curr = currWord + letterPool.substring(i, i+1);
String newLetterPool = (letterPool.substring(0, i) + letterPool.substring(i+1));
if(dict.contains(curr)) {
possibleWords.add(curr);
}
boolean prefixInDic = binarySearch(curr);
if( !prefixInDic ){
break;
} else {
getAllWords(newLetterPool, curr);
}
}
}
private static boolean binarySearch(String word){
int max = dict.size() - 1;
int min = 0;
int currIndex = 0;
boolean result = false;
while(min <= max) {
currIndex = (min + max) / 2;
if (dict.get(currIndex).startsWith(word)) {
result = true;
break;
} else if (dict.get(currIndex).compareTo(word) < 0) {
min = currIndex + 1;
} else if(dict.get(currIndex).compareTo(word) > 0){
max = currIndex - 1;
} else {
result = true;
break;
}
}
return result;
}
The simplest way to speed up your algorithm is probably to use a Trie (a prefix tree)
Trie data structures offer two relevant methods. isWord(String) and isPrefix(String), both of which take O(n) comparisons to determine whether a word or prefix exist in a dictionary (where n is the number of letters in the argument). This is really fast because it doesn't matter how large your dictionary is.
For comparison, your method for checking if a prefix exists in your dictionary using binary search is O(n*log(m)) where n is the number of letters in the string and m is the number of words in the dictionary.
I coded up a similar algorithm to yours using a Trie and compared it to the code you posted (with minor modifications) in a very informal benchmark.
With 20-char input, the Trie took 9ms. The original code didn't complete in reasonable time so I had to kill it.
Edit:
As to why your code doesn't return all hints, you don't want to break if the prefix is not in your dict. You should continue to check the next prefix instead.
Is there a recommended, faster algorithm?
See Wikipedia article on "String searching algorithm", in particular the section named "Algorithms using a finite set of patterns", where "finite set of patterns" is your dictionary.
The Aho–Corasick algorithm listed first might be a good choice.

How would I ask java to stop until a variable is changed?

so I am trying to design a GUI with the program BlueJ, that sends data from a jtextfield box into a variable (already done), and using that variable to be able to update another variable, but for java to "stop running" until a specific variable is updated. So something along the lines of...
string bacon = "";
int agility = 1;
int dexterity = 2;
int strength = 3;
int intelligence = 4;
int charisma = 5;
//my variables.
if (bacon = "agility")
{
//what I am doing goes below where words are being used instead
Stop java progression until bacon is updated with an integer.
agility= agility+bacon
}
else if (bacon = "dexterity")
{
//what I am doing goes below where words are being used instead
Stop java progression until bacon is updated with an integer.
dexterity = dexterity+bacon
}
else if (bacon = "strength")
{
//what I am doing goes below where words are being used instead
Stop java progression until bacon is updated with an integer.
strength = strength+bacon
}
else if (bacon = "intelligence")
{
//what I am doing goes below where words are being used instead
Stop java progression until bacon is updated with an integer.
intelligence = intelligence+bacon
}
else if (bacon = "charisma")
{
//what I am doing goes below where words are being used instead
Stop java progression until bacon is updated with an integer.
charisma = charisma+bacon
}
Thank you very much to anybody who can help me figure this out. I would also like it to have something so that if bacon is stated as a non-integer (32.7 or "hello"), it would simply ask you to input a proper integer.
Not quite sure what you are asking in the first part of the question, but for the second part to it check if it is a non integer you can do something like this....
boolean isValidInput = true;
for(int i=0;i<bacon.length();i++) {
char charAt = bacon.charAt(i);
if(!Character.isDigit(charAt)) {
isValidInput = false;
break;
}
}
if(!isValidInput)
System.out.println("Invalid Input!");
Also, = is used for assignment in java, ex a = 3;, however if you are trying to check if something is equal to something else, you should use the == operator. ex. if(x==2)
But in your case, since you are comparing Strings, you should use if(x.equals("hello"))
Another tip, instead of saying charisma = charisma + bacon; you can just say charisma += bacon; as a shorthand ;)
Hope this helps,
Saashin

Calculate Dice Roll from Text Field

QUESTION:
How can I read the string "d6+2-d4" so that each d# will randomly generate a number within the parameter of the dice roll?
CLARIFIER:
I want to read a string and have it so when a d# appears, it will randomly generate a number such as to simulate a dice roll. Then, add up all the rolls and numbers to get a total. Much like how Roll20 does with their /roll command for an example. If !clarifying {lstThen.add("look at the Roll20 and play with the /roll command to understand it")} else if !understandStill {lstThen.add("I do not know what to say, someone else could try explaining it better...")}
Info:
I was making a Java program for Dungeons and Dragons, only to find that I have come across a problem in figuring out how to calculate the user input: I do not know how to evaluate a string such as this.
I theorize that I may need Java's eval at the end. I do know what I want to happen/have a theory on how to execute (this is more so PseudoCode than Java):
Random rand = new Random();
int i = 0;
String toEval;
String char;
String roll = txtField.getText();
while (i<roll.length) {
check if character at i position is a d, then highlight the numbers
after d until it comes to a special character/!aNumber
// so if d was found before 100, it will then highlight 100 and stop
// if the character is a symbol or the end of the string
if d appears {
char = rand.nextInt(#);
i + #'s of places;
// so when i++ occurs, it will move past whatever d# was in case
// d# was something like d100, d12, or d5291
} else {
char = roll.length[i];
}
toEval = toEval + char;
i++;
}
perform evaluation method on toEval to get a resulting number
list.add(roll + " = " + evaluated toEval);
EDIT:
With weston's help, I have honed in on what is likely needed, using a splitter with an array, it can detect certain symbols and add it into a list. However, it is my fault for not clarifying on what else was needed. The pseudocode above doesn't helpfully so this is what else I need to figure out.
roll.split("(+-/*^)");
As this part is what is also tripping me up. Should I make splits where there are numbers too? So an equation like:
String[] numbers = roll.split("(+-/*^)");
String[] symbols = roll.split("1234567890d")
// Rough idea for long way
loop statement {
loop to check for parentheses {
set operation to be done first
}
if symbol {
loop for symbol check {
perform operations
}}} // ending this since it looks like a bad way to do it...
// Better idea, originally thought up today (5/11/15)
int val[];
int re = 1;
loop {
if (list[i].containsIgnoreCase(d)) {
val[]=list[i].splitIgnoreCase("d");
list[i] = 0;
while (re <= val[0]) {
list[i] = list[i] + (rand.nextInt(val[1]) + 1);
re++;
}
}
}
// then create a string out of list[]/numbers[] and put together with
// symbols[] and use Java's evaluator for the String
wenton had it, it just seemed like it wasn't doing it for me (until I realised I wasn't specific on what I wanted) so basically to update, the string I want evaluated is (I know it's a little unorthodox, but it's to make a point; I also hope this clarifies even further of what is needed to make it work):
(3d12^d2-2)+d4(2*d4/d2)
From reading this, you may see the spots that I do not know how to perform very well... But that is why I am asking all you lovely, smart programmers out there! I hope I asked this clearly enough and thank you for your time :3
The trick with any programming problem is to break it up and write a method for each part, so below I have a method for rolling one dice, which is called by the one for rolling many.
private Random rand = new Random();
/**
* #param roll can be a multipart roll which is run and added up. e.g. d6+2-d4
*/
public int multiPartRoll(String roll) {
String[] parts = roll.split("(?=[+-])"); //split by +-, keeping them
int total = 0;
for (String partOfRoll : parts) { //roll each dice specified
total += singleRoll(partOfRoll);
}
return total;
}
/**
* #param roll can be fixed value, examples -1, +2, 15 or a dice to roll
* d6, +d20 -d100
*/
public int singleRoll(String roll) {
int di = roll.indexOf('d');
if (di == -1) //case where has no 'd'
return Integer.parseInt(roll);
int diceSize = Integer.parseInt(roll.substring(di + 1)); //value of string after 'd'
int result = rand.nextInt(diceSize) + 1; //roll the dice
if (roll.startsWith("-")) //negate if nessasary
result = -result;
return result;
}

Scaling RGB values in Pi

So for extra credit for my math class I'm writing a program to visualize pi. Every 6 digits is converted to a hex color.
However, I'm running into an error when I try to scale the colors (since with 2 digits each for r, g, and b I can only go up to 99 and I want to go to 255). I go through a few thousand digits of pi and run this scale function on each set of 6 and then write it to a pixel in a BufferedImage, but I keep getting a StringIndexOutOfBoundsException. When I tried setting retArray[i+1] = subArray[0] I get the same error but this time at line 5. Any idea what's going on?
private String scale(int org){
tmp = Integer.toString(org);
retArray = new char[6];
for(int i=0; i<=4; i+=2){
tmpsub = tmp.substring(i, i+2); //line 5
int2 = Integer.parseInt(tmpsub);
tmpint = (((float)(int2)/99)*255);
intie = (int)(tmpint);
tmpsub = Integer.toHexString(intie);
subArray = tmpsub.toCharArray();
retArray[i] = subArray[0];
retArray[i+1] = subArray[1]; //String Index Exception on this line
}
retString = "";
for(int i=0; i<retArray.length; i++)
retString+=retArray[i];
return retString;
}
Thanks so much for any help with this problem. Hopefully it's something obvious that I don't see.
The problem is with Integer.toHexString().
If you give it a value that is less than 0x10 (16 in decimal,) you'd get a string of length one as a result, and then subArray[1] would throw an exception.

Categories

Resources