I'm making an iOS app that parses JSON data from a google spreadsheet. One of the issues with Google JSON data is that it includes unnecessary data that has to be removed. I'm new to iOS programming.
/*O_o*/google.visualization.Query.setResponse({"version":"0.6","reqId":"0","status":"ok","sig":"1400846503","table":{JSON DATA I NEED}});
I have done this in JAVA on Android using this code
int start = result.indexOf("{", result.indexOf("{") + 1);
int end = result.lastIndexOf("}");
String jsonResponse = result.substring(start, end);
My swift code
var something = "My google JSON Data"
let Start = String(something).characters.indexOf("{")!;
let substring1: String = something.substringFromIndex(Start);
something = substring1;
let End = String(something).characters.indexOf(")")!.distanceTo(something.endIndex);
let index3 = something.endIndex.advancedBy(-End);
let substring4: String = something.substringToIndex(index3)
What I'm asking is how do I get the index of the 2nd "{"
You should use NSJsonSerializer, but if you want to do it your way:
extension String {
func indexOf(target: String) -> Int {
if let range = self.rangeOfString(target) {
return self.startIndex.distanceTo(range.startIndex)
} else {
return -1
}
}
func indexOf(target: String, startIndex: Int) -> Int {
let startRange = self.startIndex.advancedBy(startIndex)
if let range = self.rangeOfString(target, options: .LiteralSearch, range: startRange..<self.endIndex) {
return self.startIndex.distanceTo(range.startIndex)
} else {
return -1
}
}
}
let end = myString.indexOf("{", startIndex: myString.indexOf("{") + 1)
Related
I've created a method in JAVA in order to do the same thing of an existing PHP function, that is: convert an arbitrarily large number from any base to any base.
The java method is working fine and I can convert numbers from one base to another and then convert it back, but the resulted strings are different from the PHP function. This is a problem to me, because I want to convert a number in PHP and then convert it back in JAVA.
For example, lets convert the number 998765;43210;9999;2 from Base11 with alphabet 0123456789; to Base21 with alphabet 0123456789ABCDEFGHIJK in PHP and JAVA:
Result of the example in PHP:
convBase("998765;43210;9999;2", "0123456789;", "0123456789ABCDEFGHIJK") = "GJK7K6B2KKGKK96"
Result of the example in JAVA:
convBase("998765;43210;9999;2", "0123456789;", "0123456789ABCDEFGHIJK") = "1B0EJAJ0IG3DABI"
I would like the results to be the same, so I could convert a number in PHP and convert it back in JAVA.
I think that the problem can be character encoding, but I don't know how to solve it.
PHP function and test:
<?php
function convBase($numberInput, $fromBaseInput, $toBaseInput)
{
if ($fromBaseInput==$toBaseInput) return $numberInput;
$fromBase = str_split($fromBaseInput,1);
$toBase = str_split($toBaseInput,1);
$number = str_split($numberInput,1);
$fromLen=strlen($fromBaseInput);
$toLen=strlen($toBaseInput);
$numberLen=strlen($numberInput);
$retval='';
if ($toBaseInput == '0123456789')
{
$retval=0;
for ($i = 1;$i <= $numberLen; $i++)
$retval = bcadd($retval, bcmul(array_search($number[$i-1], $fromBase),bcpow($fromLen,$numberLen-$i)));
return $retval;
}
if ($fromBaseInput != '0123456789')
$base10=convBase($numberInput, $fromBaseInput, '0123456789');
else
$base10 = $numberInput;
if ($base10<strlen($toBaseInput))
return $toBase[$base10];
while($base10 != '0')
{
$retval = $toBase[bcmod($base10,$toLen)].$retval;
$base10 = bcdiv($base10,$toLen,0);
}
return $retval;
}
header('Content-Type: text/html; charset=utf-8');
$number = "998765;43210;9999;2";
$fromBase = "0123456789;";
$toBase = "0123456789ABCDEFGHIJK";
$converted = convBase($number, $fromBase, $toBase);
$back = convBase($converted, $toBase, $fromBase);
echo "Number: ".$number."<br>";
echo "Converted: ".$converted."<br>";
echo "Back: ".$back."<br>";
?>
JAVA method and test:
import java.math.BigInteger;
public class ConvBase{
public static String convBase(String number, String fromBaseInput, String toBaseInput){
if (fromBaseInput.equals(toBaseInput))
return number;
BigInteger fromLen = new BigInteger(""+fromBaseInput.length());
BigInteger toLen = new BigInteger(""+toBaseInput.length());
BigInteger numberLen = new BigInteger(""+number.length());
if(toBaseInput.equals("0123456789")){
BigInteger retval = BigInteger.ZERO;
for(int i=1; i<=number.length(); i++){
retval = retval.add(
new BigInteger(""+fromBaseInput.indexOf(number.charAt(i-1))).multiply(
fromLen.pow(numberLen.subtract(new BigInteger(""+i)).intValue())
//pow(fromLen, numberLen.subtract(new BigInteger(""+i)))
)
);
}
return ""+retval;
}
String base10 = fromBaseInput.equals("0123456789") ? number : convBase(number, fromBaseInput, "0123456789");
if(new BigInteger(base10).compareTo(toLen) < 0)
return ""+toBaseInput.charAt(Integer.parseInt(base10));
String retVal = "";
BigInteger base10bigInt = new BigInteger(base10);
while(!base10bigInt.equals(BigInteger.ZERO)){
retVal = toBaseInput.charAt(base10bigInt.mod(toLen).intValue()) + retVal;
base10bigInt = base10bigInt.divide(toLen);
}
return ""+retVal;
}
public static void main(String[] args) {
String number = "98765;43210;9999;2";
String fromBase = "0123456789;";
String toBase = "0123456789ABCDEFGHIJK";
String converted = ConvBase.convBase(number, fromBase, toBase);
String back = ConvBase.convBase(converted, toBase, fromBase);
System.out.println("Number = "+number);
System.out.println("Converted = "+converted);
System.out.println("Back = "+back);
System.exit(0);
}
}
There is a typo in your test case. Both programs seem to be correct, or at least consistent.
Your Java variant converts "98765;43210;9999;2" while your PHP program converts "998765;43210;9999;2". Note the two nines at the beginning. When I changed the number I got the following output:
Number = 998765;43210;9999;2
Converted = GJK7K6B2KKGKK96
Back = 998765;43210;9999;2
which is consistent with the output of the PHP version.
I have doubt in that section. How to Remove country code, when I pick phone number from contact list?
Ex: +91 999999999 instead of 9999999999 or +020 9696854549 instead of 9696854549 Can any one know the answer about my question. please give solution to this problem
I attached my code and image here.
private void contactPicked(Intent data) {
Cursor cursor = null;
try {
String phoneNo = null ;
// getData() method will have the Content Uri of the selected contact
Uri uri = data.getData();
//Query the content uri
cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
// column index of the phone number
int phoneIndex =cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER
phoneNo = cursor.getString(phoneIndex);
String phoneNumber = phoneNo.replaceAll(" ","");
mobile_et.setText(phoneNumber);
} catch (Exception e) {
e.printStackTrace();
}
}
You can use startsWith()
This method has two variants and tests if a string starts with the
specified prefix beginning a specified index or by default at the
beginning.
if(phoneNumber.startsWith("+"))
{
if(phoneNumber.length()==13)
{
String str_getMOBILE=phoneNumber.substring(3);
mobile_et.setText(str_getMOBILE);
}
else if(phoneNumber.length()==14)
{
String str_getMOBILE=phoneNumber.substring(4);
mobile_et.setText(str_getMOBILE);
}
}
else
{
mobile_et.setText(phoneNumber);
}
My English is poor, but I will try my best to answer your question.
First of all , add this line to your build.gradle
compile 'com.googlecode.libphonenumber:libphonenumber:8.7.0'
And below is a sample write by kotlin
fun deleteCountry(phone: String) : String{
val phoneInstance = PhoneNumberUtil.getInstance()
try {
val phoneNumber = phoneInstance.parse(phone, null)
return phoneNumber?.nationalNumber?.toString()?:phone
}catch (_ : Exception) {
}
return phone
}
If phone number not start with a '+' followed by the country calling code then you should pass region information, for example:
val phoneNumber = phoneInstance.parse(phone, "CN")
Try this....
if(number.length()>10)
{
int startidx=number.length()-10;
String getnumber=number.substring(startidx,number.length());
etEmerNumber.setText(getnumber);
}
else
{
etEmerNumber.setText(number);
}
I am just simply extending the answer that If you don't want to use any library then you can do it in this way. In order to match any prefix and since some countries could share partially the same prefix (for example 91 and 91-721), you add all possibilities to the regex in descending order and size.
Follow this Code:
public static String PhoneNumberWithoutCountryCode(String phoneNumberWithCountryCode){//+91 7698989898
Pattern compile = Pattern.compile("\\+(?:998|996|995|994|993|992|977|976|975|974|973|972|971|970|968|967|966|965|964|963|962|961|960|886|880|856|855|853|852|850|692|691|690|689|688|687|686|685|683|682|681|680|679|678|677|676|675|674|673|672|670|599|598|597|595|593|592|591|590|509|508|507|506|505|504|503|502|501|500|423|421|420|389|387|386|385|383|382|381|380|379|378|377|376|375|374|373|372|371|370|359|358|357|356|355|354|353|352|351|350|299|298|297|291|290|269|268|267|266|265|264|263|262|261|260|258|257|256|255|254|253|252|251|250|249|248|246|245|244|243|242|241|240|239|238|237|236|235|234|233|232|231|230|229|228|227|226|225|224|223|222|221|220|218|216|213|212|211|98|95|94|93|92|91|90|86|84|82|81|66|65|64|63|62|61|60|58|57|56|55|54|53|52|51|49|48|47|46|45|44\\D?1624|44\\D?1534|44\\D?1481|44|43|41|40|39|36|34|33|32|31|30|27|20|7|1\\D?939|1\\D?876|1\\D?869|1\\D?868|1\\D?849|1\\D?829|1\\D?809|1\\D?787|1\\D?784|1\\D?767|1\\D?758|1\\D?721|1\\D?684|1\\D?671|1\\D?670|1\\D?664|1\\D?649|1\\D?473|1\\D?441|1\\D?345|1\\D?340|1\\D?284|1\\D?268|1\\D?264|1\\D?246|1\\D?242|1)\\D?");
String number = phoneNumberWithCountryCode.replaceAll(compile.pattern(), "");
//Log.e(tag, "number::_>" + number);//OutPut::7698989898
return number;
}
It will work for all instances. You need not care about how much digit the country code is
String get_Mo = phoneNumber.substring(phoneNumber.lastIndexOf(' ')+1));
If you can use a library, this might help you:
Gradle:
repositories {
mavenCentral()
}
dependencies {
implementation 'io.michaelrocks:libphonenumber-android:8.12.51'
}
Java:
String getPhoneNummberWithoutCountryCode(String phoneNo)
{
PhoneNumberUtil phoneInstance = PhoneNumberUtil.createInstance(this.getContext());
Phonenumber.PhoneNumber phoneNumber = phoneInstance.parse(phoneNo, null);
String nationalSignificantNumber = phoneInstance.getNationalSignificantNumber(phoneNumber);
return nationalSignificantNumber;
}
nationalSignificantNumber is the required phone number
use this function hope it will help you out:
public String phoeNumberWithOutCountryCode(String phoneNumberWithCountryCode) {
Pattern complie = Pattern.compile(" ");
String[] phonenUmber = complie.split(phoneNumberWithCountryCode);
Log.e("number is", phonenUmber[1]);
return phonenUmber[1];
}
String Trimmed = s.toString().trim();
if(Trimmed.length() > 10){
char[] number = Trimmed.toCharArray();
int extra;
int dif = Trimmed.length() - 10 ;
for(int i = dif; i < Trimmed.length() ; i++){
extra = i-dif;
number[extra] = number[i];
}
for (int i = 10 ; i < Trimmed.length() ; i++){
number[i]=' ';
}
String finalNumber = String.valueOf(number);
MobileNumberET.setText(finalNumber.trim());
}
//paste this in your text change listener
Use a library
https://groups.google.com/forum/?hl=en&fromgroups#!forum/libphonenumber-discuss
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
// phone must begin with '+'
PhoneNumber numberProto = phoneUtil.parse(phone, "");
int countryCode = numberProto.getCountryCode();
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
If you'd like to perform some extra function on a particular Sim on the mobile you can use some of the many methods below.
Might not be a perfect solution but, I'll try my best.
First get the country code programmatically :
TelephonyManager tm = (TelephonyManager)
this.getSystemService(Context.TELEPHONY_SERVICE);
//get the country iso from sim e.g US, NG, FR etc
String countryIso = tm.getSimCountryIso().toUpperCase():
//get countrycode from refegion returns the code e.g +123, +1, +23 etc.
Int countryCode =
phoneNumberUtil.getInstance().getCountryCodeForRegion(countryIso);
Then you can remove it using your preferred way likeString PhoneNumber = phoneNo.replaceAll("countryCode ", "" );
First of all, make sure your given phone number should be in a Normalized format
like
+921234567
then use the libphonenumber google library, so, in build.gradle add this
implementation 'com.googlecode.libphonenumber:libphonenumber:8.13.4'
then follow the below code:
val phoneUtil = PhoneNumberUtil.getInstance()
try {
val phoneNumberProto: Phonenumber.PhoneNumber = phoneUtil.parse(number, null)
val numberWithoutCountryCode = phoneUtil.getNationalSignificantNumber(phoneNumberProto)
Log.d(Constant.LOG_APP_DEBUG, "PhoneNumber: $numberWithoutCountryCode")
} catch (e: NumberParseException) {
Log.d(Constant.LOG_APP_DEBUG, "NumberParseException was thrown: $e")
}
I am trying to remove subdomain and leave only the domain name followed by the extension.
It is difficult to find the subdomain because I do not know how many dots to expect in a url. some urls end in .com some in .co.uk for example.
How can I remove the subdomain safely so that foo.bar.com becomes bar.com and foo.bar.co.uk becomes bar.co.uk
if(!rawUrl.startsWith("http://")&&!rawUrl.startsWith("https://")){
rawUrl = "http://"+rawUrl;
}
String url = new java.net.URL(rawUrl).getHost();
String urlWithoutSub = ???
What you need is a Public Sufix List, such as the one available at https://publicsuffix.org/. Basically, there is no algorithm that can tell you which suffixes are public, so you need a list. And you’d better used one that is public and well-maintained.
just stumped upon this question and decided to write the following function.
Example Input -> Output:
http://example.com -> http://example.com
http://www.example.com -> http://example.com
ftp://www.a.example.com -> ftp://example.com
SFTP://www.a.example.com -> SFTP://example.com
http://www.a.b.example.com -> http://example.com
http://www.a.c.d.example.com -> http://example.com
http://example.com/ -> http://example.com/
https://example.com/aaa -> http://example.com/aaa
http://www.example.com/aa/bb../d -> http://example.com/aa/bb../d
FILE://www.a.example.com/ddd/dd/../ff -> FILE://example.com/ddd/dd/../ff
HTTPS://www.a.b.example.com/index.html?param=value -> HTTPS://example.com/index.html?param=value
http://www.a.c.d.example.com/#yeah../..! -> http://lmao.com/#yeah../..!
Same goes for second level domains
http://some.thing.co.uk/?ke - http://thing.co.uk/?ke
something.co.uk/?ke - something.co.uk/?ke
www.something.co.uk/?ke - something.co.uk/?ke
www.something.co.uk - something.co.uk
https://www.something.co.uk - https://something.co.uk
Code:
public static String removeSubdomains(String url, ArrayList<String> secondLevelDomains) {
// We need our URL in three parts, protocol - domain - path
String protocol= getProtocol(url);
url = url.substring(protocol.length());
String urlDomain=url;
String path="";
if(urlDomain.contains("/")) {
int slashPos = urlDomain.indexOf("/");
path=urlDomain.substring(slashPos);
urlDomain=urlDomain.substring(0, slashPos);
}
// Done, now let us count the dots . .
int dotCount = Strng.countOccurrences(urlDomain, ".");
// example.com <-- nothing to cut
if(dotCount==1){
return protocol+url;
}
int dotOffset=2; // subdomain.example.com <-- default case, we want to remove everything before the 2nd last dot
// however, somebody had the glorious idea, to have second level domains, such as co.uk
for (String secondLevelDomain : secondLevelDomains) {
// we need to check if our domain ends with a second level domain
// example: something.co.uk we don't want to cut away "something", since it isn't a subdomain, but the actual domain
if(urlDomain.endsWith(secondLevelDomain)) {
// we increase the dot offset with the amount of dots in the second level domain (co.uk = +1)
dotOffset += Strng.countOccurrences(secondLevelDomain, ".");
break;
}
}
// if we have something.co.uk, we have a offset of 3, but only 2 dots, hence nothing to remove
if(dotOffset>dotCount) {
return protocol+urlDomain+path;
}
// if we have sub.something.co.uk, we have a offset of 3 and 3 dots, so we remove "sub"
int pos = Strng.nthLastIndexOf(dotOffset, ".", urlDomain)+1;
urlDomain = urlDomain.substring(pos);
return protocol+urlDomain+path;
}
public static String getProtocol(String url) {
String containsProtocolPattern = "^([a-zA-Z]*:\\/\\/)|^(\\/\\/)";
Pattern pattern = Pattern.compile(containsProtocolPattern);
Matcher m = pattern.matcher(url);
if (m.find()) {
return m.group();
}
return "";
}
public static ArrayList<String> getPublicSuffixList(boolean loadFromPublicSufficOrg) {
ArrayList<String> secondLevelDomains = new ArrayList<String>();
if(!loadFromPublicSufficOrg) {
secondLevelDomains.add("co.uk");secondLevelDomains.add("co.at");secondLevelDomains.add("or.at");secondLevelDomains.add("ac.at");secondLevelDomains.add("gv.at");secondLevelDomains.add("ac.at");secondLevelDomains.add("ac.uk");secondLevelDomains.add("gov.uk");secondLevelDomains.add("ltd.uk");secondLevelDomains.add("fed.us");secondLevelDomains.add("isa.us");secondLevelDomains.add("nsn.us");secondLevelDomains.add("dni.us");secondLevelDomains.add("ac.ru");secondLevelDomains.add("com.ru");secondLevelDomains.add("edu.ru");secondLevelDomains.add("gov.ru");secondLevelDomains.add("int.ru");secondLevelDomains.add("mil.ru");secondLevelDomains.add("net.ru");secondLevelDomains.add("org.ru");secondLevelDomains.add("pp.ru");secondLevelDomains.add("com.au");secondLevelDomains.add("net.au");secondLevelDomains.add("org.au");secondLevelDomains.add("edu.au");secondLevelDomains.add("gov.au");
}
try {
String a = URLHelpers.getHTTP("https://publicsuffix.org/list/public_suffix_list.dat", false, true);
Scanner scanner = new Scanner(a);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if(!line.startsWith("//") && !line.startsWith("*") && line.contains(".")) {
secondLevelDomains.add(line);
}
}
scanner.close();
} catch (Exception e) {
e.printStackTrace();
}
return secondLevelDomains;
}
I am trying to get the content of a single array item.
In my code, I want the value of String suitId to have the content of suitIdArray[getSuitId];, but it doesn't get the content.
Could you please help me to see what is wrong. Here is my code...
Object item1 = spinner1.getSelectedItem();
int getDragId = spinner1.getSelectedItemPosition();
String suitId;
if(!item1.equals("Choose size")) {
suitId = suitIdArray[getSuitId];
}
else {
pSuit = null;
}
Is is not working because you have a variable getdragid but you're using getsuitid in the array? ie, should it be the following...
Object item1 = spinner1.getSelectedItem();
int getdragtid = spinner1.getSelectedItemPosition();
if(!item1.equals("Choose size"))
{
suitid = suitidarray[getdragtid]; // I changed this line
}
else if(item1.equals("Choose size"))
{
psuit = null;
}
Otherwise, I'm not really sure what you're trying to do?
I have the following String:
oauth_token=safcanhpyuqu96vfhn4w6p9x&**oauth_token_secret=hVhzHVVMHySB**&application_name=Application_Name&login_url=https%3A%2F%2Fapi-user.netflix.com%2Foauth%2Flogin%3Foauth_token%3Dsafcanhpyuqu96vfhn4w6p9x
I am trying to parse out the value for oauth_token_secret. I need everything from the equals sign (=) to the next ampersand sign (&). So I need to parse out: hVhzHVVMHySB
Currently, I have the following code:
Const.OAUTH_TOKEN_SECRET = "oauth_token_secret";
Const.tokenSecret =
content.substring(content.indexOf((Const.OAUTH_TOKEN_SECRET + "="))
+ (Const.OAUTH_TOKEN_SECRET + "=").length(),
content.length());
This will start at the beginning of the oauth_token_string, but it will not stop at the next ampersand. I am unsure how to specify to stop at the end of the following ampersand. Can anyone help me?
The indexOf() methods allow you to specify an optional fromIndex. This allows you to find the next ampersand:
int oauth = content.indexOf(Const.OAUTH_TOKEN_SECRET);
if (oauth != -1) {
int start = oath + Const.OATH_TOKEN_SECRET.length(); // or
//int start = content.indexOf('=', oath) + 1;
int end = content.indexOf('&', start);
String tokenSecret = end == -1 ? content.substring(start) : content.substring(start, end);
}
public static Map<String, String> buildQueryMap(String query)
{
String[] params = query.split("&");
Map<String, String> map = new HashMap<String, String>();
for (String param : params)
{
String[] pair = param.split("=");
String name = pair[0];
String value = pair[1];
map.put(name, value);
}
return map;
}
// in your code
Map<String, String> queryMap = buildQueryMap("a=1&b=2&c=3....");
String tokenSecret = queryMap.get(Const.OAUTH_TOKEN_SECRET);
Using String.split gives a much cleaner solution.
static String getValue(String key, String content) {
String[] tokens = content.split("[=&]");
for(int i = 0; i < tokens.length - 1; ++i) {
if(tokens[i].equals(key)) {
return tokens[i+1];
}
}
return null;
}
Click here for a test drive! ;-)
A much better solution is using the Pattern and corresponding Matcher class.
By using a capturing group you can check and "cut out" the the appropriate substring in one step.