String uRL = JOptionPane.showInputDialog("Enter a URL "); int colon = uRL.indexOf(":");
System.out.println("The position of colon is "+ colon);
String protocol = uRL.substring(0,colon);
System.out.println("the protocol is "+ protocol);
// Declare Statements, extract and print the second part
String restOFURL = uRL.substring(colon+7);
System.out.println("The rest of Url is "+restOFURL);
int positionOfSlash1 = restOFURL.indexOf("/");
System.out.println(positionOfSlash1);
Ok so the input will be a URL, let just say for example the URL is http://www.pcwebopedia.com/files/index.html
URL will always have let say the HTTP FTTP: // www. and etc
The project that Im doing is to break down URL into different parts and I'm stuck on one of the question
The question ask me to find the position Of Slash 1, as you see in the code rest of URL is
pcwebopedia.com/files/index.html the position is 15 for the first /
while http://www.pcwebopedia.com/files/index.html is 26, this is what I want.
There was a suggestion that said to first find how many characters there is from start of the string to period "www." and add the value to positionOfSlash1
the indexOf() method also take a second parameter (fromIndex) which is used to specify to say indexOf from where you try to lookup for the parameter:
int positionOfSlash1 = restOFURL.indexOf("/", colon + 3);
positionOfSlash1 = uRL.indexOf("/", colon + 3);
There are many ways to do it. I would do it using Java Regex API.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(final String args[]) {
// Test
System.out.println(indexOfDomainNameSeparator("pcwebopedia.com/files/index.html"));
System.out.println(indexOfDomainNameSeparator("http://www.pcwebopedia.com/files/index.html"));
System.out.println(indexOfDomainNameSeparator("Hello WOrld"));
}
static int indexOfDomainNameSeparator(String url) {
String regex = "(?<![:/])/";
Matcher matcher = Pattern.compile(regex).matcher(url);
// If found, return the index; otherwise, return -1
return matcher.find() ? matcher.start() : -1;
}
}
Output:
15
26
-1
The regex, (?<![:/])/ means / not preceded by a : or /. In regex terminology, 'not preceded by' is known as the negative lookbehind. The thing inside [ ] is known as character classes.
Alternatively, using String#indexOf(int,%20int) and String.html#indexOf(int):
public class Main {
public static void main(final String args[]) {
// Test
System.out.println(indexOfDomainNameSeparator("pcwebopedia.com/files/index.html"));
System.out.println(indexOfDomainNameSeparator("http://www.pcwebopedia.com/files/index.html"));
System.out.println(indexOfDomainNameSeparator("Hello WOrld"));
}
static int indexOfDomainNameSeparator(String url) {
int indexOfColon = url.indexOf(':');
if (indexOfColon != -1) {
return url.indexOf('/', indexOfColon + 3);// Starting from indexOfColon + 3
} else {
return url.indexOf('/');
}
}
}
Output:
15
26
-1
Related
2 possible strings contained in a log file:
1) "some text then https://myhost.ab.us2.myDomain.com and then some more text"
OR:
2) "some text then myhost.ab.us2.myDomain.com and then some more text"
The "myDomain.com" is constant, so we can look for that hard-coded in the regex.
In both cases, they are not at the start of the line, but in the middle.
Need to extract "myhost" out of the line, if it matches.
I've tried positive look behind using "https://" OR "\\s{1}". The https:// by itself works:
Matcher m = Pattern.compile("https://(.+?)\\.(.+?)\\.(.+?)\\.myDomain\\.com\\s").matcher(input);
I'm want to add an "or" in there so it matches with "https://" or "<space>" ("https://|//s{1}"), but it always grabs the entire string up to the start of the first space.
For now, I've settled on splitting the string into String[] and checking if it contains "myDomain". I worked so long on this I wanted to learn what the best answer is.
I just put in a non-regex approach:
public static String extractHost(String logEntry, String domain)
{
logEntry = logEntry.toLowerCase(); -> not needed, just a hint to remember case sensitive stuff ;)
if(logEntry.indexOf("https://") != -1)
{
// contains protocol, must be variant one
return logEntry.substring(logEntry.indexOf("https://")+8,logEntry.indexOf("."));
}
// has to be variant two
int domainIndex = logEntry.indexOf(domain);
if(domainIndex == -1) return null;
int previousDotIndex = -1;
for(int i = domainIndex; i>= 0; i--)
{
if(logEntry.charAt(i) == '.') previousDotIndex = i;
if(logEntry.charAt(i) == ' ') return logEntry.substring(++i,previousDotIndex);
}
return null;
}
The variant #2 is actually the more difficult one, in this approach you just iterate from the domain's index back to the first whitespace found and store the position of the most recent dot found. Then it's just a simple substring.
I'd use something like
\b(?:https?:\/\/)?(\w+)\.(?:\w+\.)*myDomain\.com
This matches an optional https:// prefix followed by your host which is captured, followed by some other subdomains (you could specify how many with {2} or hardcode them in, if you know it's always ab.us2), then myDomain.com.
In Java 10:
import java.util.Arrays;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
var text = "some text then https://myhost.ab.us2.myDomain.com " +
"and then some more text some text then " +
"myhost.ab.us2.myDomain.com and then some more text";
var pat = "\\b(?:https?://)?(\\w+)\\.(?:\\w+\\.)*myDomain\\.com";
var matches = Pattern.compile(pat)
.matcher(text)
.results()
.map((m) -> m.group(1))
.toArray(String[]::new);
System.out.println(Arrays.toString(matches)); // => [myhost, myhost]
}
}
In Java 8:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String text = "some text then https://myhost.ab.us2.myDomain.com " +
"and then some more text some text then " +
"myhost.ab.us2.myDomain.com and then some more text";
String pat = "\\b(?:https?://)?(\\w+)\\.(?:\\w+\\.)*myDomain\\.com";
Matcher matcher = Pattern.compile(pat).matcher(text);
while (matcher.find()) {
System.out.println(matcher.group(1)); // => myhost myhost
}
}
}
Can you help me to understand why my code doesn't work, please?
I am trying to get values from 2 columns from my database and store them in a hashmap where K_PARAM is my key and L_PARAM is my value. Then I would like to compare 2 characters from a line that I am extracting and see if these 2 characters are equals to my key or not. In case they are equals, I replace key with value.
Thanks in advance. This is the code :
if (action.equals("RP")) {
if (marqueCarte = null) {
jdbcTemplate.query(" select K_PARAM, L_PARAM from DLCOA.DLC_ADM_PARAMS where K_CHX_PARAM = '50'", new ResultSetExtractor<Map>(){
#Override
public Map extractData(ResultSet rs) throws SQLException,DataAccessException {
HashMap<String,String> marqueCarte = new HashMap<String,String>();
while (rs.next()) {
marqueCarte.put(rs.getString("K_PARAM"),rs.getString("L_PARAM"));
if (line.contains("blocE")) {
if (line.substring(line.indexOf("blocE") + 15, line.indexOf("blocE") + 15 + (line.substring(line.indexOf("blocE")+15)).indexOf("#")).equals(rs.getString("K_PARAM"))){
line = line.replace(line.substring(line.indexOf("blocE") + 15, line.indexOf("blocE") + 15 + (line.substring(line.indexOf("blocE")+15)).indexOf("#")),rs.getString("L_PARAM") );
}
}
}
return marqueCarte;
}
}
}
}
I got a more readable and modifiable solution for your second problem.
(I'm still not sure what's your first one)
Using regex and patterns you can achieve the replacement you want.
Let's assume that you are searching for the text "blocE" followed by 15 characters, followed at the same time by the text contained in rs.getString("K_PARAM") plus an "#"
We can model what you search as a pattern like this
"(blocE)(.{15})(" + key + "#)"
Parenthesis allow us to establish different groups in the regex.
Group 1 - blocE
Group 2 - 15 characters
Group 3 - key + #
Being group 0 the complete matching expression.
Knowing this you can do the replacement applying the following code
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestRegex {
public static void main(String[] args) {
String key = "KEY"; // rs.getString("K_PARAM")
String value = "VALUE"; // rs.getString("L_PARAM")
Pattern pattern = Pattern.compile("(blocE)(.{15})(" + key + "#)");
String input ="helloworldblocE111111111111111KEY#blocE111111111111111KEY";
Matcher m = pattern.matcher(input);
if (m.find()) {
String text2replace = m.group(0);
String replacement = m.group(1) + m.group(2) + value;
System.out.println(input.replaceFirst(text2replace, replacement));
}
}
}
If your pattern changes, you only have to change one line and you do not have to worry about such quantity of indexOf.
I am trying to mask email address with "*" but I am bad at regex.
input : nileshxyzae#gmail.com
output : nil********#gmail.com
My code is
String maskedEmail = email.replaceAll("(?<=.{3}).(?=[^#]*?.#)", "*");
but its giving me output nil*******e#gmail.com I am not getting whats getting wrong here. Why last character is not converted?
Also can someone explain meaning all these regex
Your look-ahead (?=[^#]*?.#) requires at least 1 character to be there in front of # (see the dot before #).
If you remove it, you will get all the expected symbols replaced:
(?<=.{3}).(?=[^#]*?#)
Here is the regex demo (replace with *).
However, the regex is not a proper regex for the task. You need a regex that will match each character after the first 3 characters up to the first #:
(^[^#]{3}|(?!^)\G)[^#]
See another regex demo, replace with $1*. Here, [^#] matches any character that is not #, so we do not match addresses like abc#example.com. Only those emails will be masked that have 4+ characters in the username part.
See IDEONE demo:
String s = "nileshkemse#gmail.com";
System.out.println(s.replaceAll("(^[^#]{3}|(?!^)\\G)[^#]", "$1*"));
If you're bad at regular expressions, don't use them :) I don't know if you've ever heard the quote:
Some people, when confronted with a problem, think
"I know, I'll use regular expressions." Now they have two problems.
(source)
You might get a working regular expression here, but will you understand it today? tomorrow? in six months' time? And will your colleagues?
An easy alternative is using a StringBuilder, and I'd argue that it's a lot more straightforward to understand what is going on here:
StringBuilder sb = new StringBuilder(email);
for (int i = 3; i < sb.length() && sb.charAt(i) != '#'; ++i) {
sb.setCharAt(i, '*');
}
email = sb.toString();
"Starting at the third character, replace the characters with a * until you reach the end of the string or #."
(You don't even need to use StringBuilder: you could simply manipulate the elements of email.toCharArray(), then construct a new string at the end).
Of course, this doesn't work correctly for email addresses where the local part is shorter than 3 characters - it would actually then mask the domain.
Your Look-ahead is kind of complicated. Try this code :
public static void main(String... args) throws Exception {
String s = "nileshkemse#gmail.com";
s= s.replaceAll("(?<=.{3}).(?=.*#)", "*");
System.out.println(s);
}
O/P :
nil********#gmail.com
I like this one because I just want to hide 4 characters, it also dynamically decrease the hidden chars to 2 if the email address is too short:
public static String maskEmailAddress(final String email) {
final String mask = "*****";
final int at = email.indexOf("#");
if (at > 2) {
final int maskLen = Math.min(Math.max(at / 2, 2), 4);
final int start = (at - maskLen) / 2;
return email.substring(0, start) + mask.substring(0, maskLen) + email.substring(start + maskLen);
}
return email;
}
Sample outputs:
my.email#gmail.com > my****il#gmail.com
info#mail.com > i**o#mail.com
//In Kotlin
val email = "nileshkemse#gmail.com"
val maskedEmail = email.replace(Regex("(?<=.{3}).(?=.*#)"), "*")
public static string GetMaskedEmail(string emailAddress)
{
string _emailToMask = emailAddress;
try
{
if (!string.IsNullOrEmpty(emailAddress))
{
var _splitEmail = emailAddress.Split(Char.Parse("#"));
var _user = _splitEmail[0];
var _domain = _splitEmail[1];
if (_user.Length > 3)
{
var _maskedUser = _user.Substring(0, 3) + new String(Char.Parse("*"), _user.Length - 3);
_emailToMask = _maskedUser + "#" + _domain;
}
else
{
_emailToMask = new String(Char.Parse("*"), _user.Length) + "#" + _domain;
}
}
}
catch (Exception) { }
return _emailToMask;
}
I want to validate a phone number in such Way :-
The field should allow the user to enter characters and should auto-correct. So an entry of "+1-908-528-5656" would not create an error for the user, it would just change to "19085285656".
I also want to number range between 9 to 11.
I also tried with the below code but not concluded to the final solution:
final String PHONE_REGEX = "^\\+([0-9\\-]?){9,11}[0-9]$";
final Pattern pattern = Pattern.compile(PHONE_REGEX);
String phone = "+1-908-528-5656";
phone=phone.replaceAll("[\\-\\+]", "");
System.out.println(phone);
final Matcher matcher = pattern.matcher(phone);
System.out.println(matcher.matches());
You can use simple String.matches(regex) to test any string against a regex pattern instead of using Pattern and Matcher classes.
Sample:
boolean isValid = phoneString.matches(regexPattern);
Find more examples
Here is the regex pattern as per your input string:
\+\d(-\d{3}){2}-\d{4}
Online demo
Better use Spring validation annotation for validation.
Example
// The Regex not validate mobile number, which is in internation format.
// The Following code work for me.
// I have use libphonenumber library to validate Number from below link.
// http://repo1.maven.org/maven2/com/googlecode/libphonenumber/libphonenumber/8.0.1/
// https://github.com/googlei18n/libphonenumber
// Here, is my source code.
public boolean isMobileNumberValid(String phoneNumber)
{
boolean isValid = false;
// Use the libphonenumber library to validate Number
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber swissNumberProto =null ;
try {
swissNumberProto = phoneUtil.parse(phoneNumber, "CH");
} catch (NumberParseException e) {
System.err.println("NumberParseException was thrown: " + e.toString());
}
if(phoneUtil.isValidNumber(swissNumberProto))
{
isValid = true;
}
// The Library failed to validate number if it contains - sign
// thus use regex to validate Mobile Number.
String regex = "[0-9*#+() -]*";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(phoneNumber);
if (matcher.matches()) {
isValid = true;
}
return isValid;
}
Assuming your input field take any kind of character and you just want the digits.
String phone = "+1-908-528-5656";
phone=phone.replaceAll("[\\D]","");
if(phone.length()>=9 || phone.length()<=11)
System.out.println(phone);
We can use String.matches(String regex)1 to validate phone numbers using java.
Sample code snippet
package regex;
public class Phone {
private static boolean isValid(String s) {
String regex = "\\d{3}-\\d{3}-\\d{4}"; // XXX-XXX-XXXX
return s.matches(regex);
}
public static void main(String[] args) {
System.out.println(isValid("123-456-7890"));
}
}
P.S. The regex pattern we use extra '\' for escaping when we use in java string. (Try to use "\d{3}-\d{3}-\d{4}" in java program, you will get an error.
Assuming you want an optimization (which is what your comment suggests).
How bout this? (the "0" is to exclude if they give complete garbage without even a single digit).
int parse(String phone){
int num = Integer.parseInt("0"+phone.replaceAll("[^0-9]",""));
return 100000000<=num&&num<100000000000?num:-1;
}
I am not sure but removing the garbage characters parenthesis, spaces and hyphens, if you match with ^((\+[1-9]?[0-9])|0)?[7-9][0-9]{9}$ , you may validate a mobile number
private static final String PHONE_NUMBER_GARBAGE_REGEX = "[()\\s-]+";
private static final String PHONE_NUMBER_REGEX = "^((\\+[1-9]?[0-9])|0)?[7-9][0-9]{9}$";
private static final Pattern PHONE_NUMBER_PATTERN = Pattern.compile(PHONE_NUMBER_REGEX);
public static boolean validatePhoneNumber(String phoneNumber) {
return phoneNumber != null && PHONE_NUMBER_PATTERN.matcher(phoneNumber.replaceAll(PHONE_NUMBER_GARBAGE_REGEX, "")).matches();
}
One easy and simple to use java phone validation regex:
public static final String PHONE_VERIFICATION = "^[+0-9-\\(\\)\\s]*{6,14}$";
private static Pattern p;
private static Matcher m;
public static void main(String[] args)
{
//Phone validation
p = Pattern.compile(PHONE_VERIFICATION);
m = p.matcher("+1 212-788-8609");
boolean isPhoneValid = m.matches();
if(!isPhoneValid)
{
System.out.println("The Phone number is NOT valid!");
return;
}
System.out.println("The Phone number is valid!");
}
i have done testing one regex for this combination of phone numbers
(294) 784-4554
(247) 784 4554
(124)-784 4783
(124)-784-4783
(124) 784-4783
+1(202)555-0138
THIS REGEX SURELY WILL BE WORKING FOR ALL THE US NUMBERS
\d{10}|(?:\d{3}-){2}\d{4}|\(\d{3}\)\d{3}-?\d{4}|\(\d{3}\)-\d{3}-?\d{4}|\(\d{3}\) \d{3} ?\d{4}|\(\d{3}\)-\d{3} ?\d{4}|\(\d{3}\) \d{3}-?\d{4}
Building on #k_g's answers, but for US numbers.
static boolean isValidTelephoneNumber(String number) {
long num = Long.parseLong("0" + number.replaceAll("[^0-9]", ""));
return 2000000000L <= num && num < 19999999999L;
}
public static void main(String[] args) {
var numbers = List.of("+1 212-788-8609", "212-788-8609", "1 212-788-8609", "12127888609", "2127888609",
"7143788", "736103355");
numbers.forEach(number -> {
boolean isPhoneValid = isValidTelephoneNumber(number);
log.debug(number + " matches = " + isPhoneValid);
});
}
I have a program where I want to filter Strings with a set number of "+"'s at the beginning.
For example:
+++Adam is working very well.
++Adam is working well.
+Adam is doing OK.
How do I only pick up each particular case (i.e. only one plus sign, only two plus signs, only three plus signs)? I usually get a return of anything beginning with a +.
I have the following regex patterns compiled, but I either get only one return (usually the two ++) or all of them:
public static String regexpluschar = "^\\Q+\\E{1}[\\w <]";
public static String regexpluspluschar = "^\\Q+\\E{2}[\\w <]";
public static String regexpluspluspluschar = "^\\Q+\\E{3}[\\w <]";
Pattern plusplusplus = Pattern.compile(regexpluspluspluschar);
Pattern plusplus = Pattern.compile(regexpluspluschar);
Pattern plus = Pattern.compile(regexpluschar);
I then try to find using a Matcher class - I've used .find() and .matches() but don't get the result I'm after (java+regex newbie alert here).
Matcher matcherplusplusplus = plusplusplus.matcher(check);
Matcher matcherplusplus = plusplus.matcher(check);
Matcher matcherplus = plus.matcher(check);
//OK we have 3+'s
if ((matcherplusplusplus.find())==true){
System.out.println("Filtering 3 +s.");
System.out.println("filter is " + filter + " in the 3 + filter.");
String toChange = getItem(i);
setItemFiltered(i, toChange);
}
//OK - we have 2 +'s
if ((matcherplusplus.find())==true){
System.out.println("Filtering 2 +s.");
System.out.println("filter is " + filter + " in the 2 + filter.");
String toChange = getItem(i);
setItemFiltered(i, toChange);
}
//OK - we have 1 +'s
if ((matcherplus.find())==true){
System.out.println("Filtering 1 +.");
System.out.println("filter is " + filter + " in the 1 + filter.");
String toChange = getItem(i);
setItemFiltered(i, toChange);
}
For the very curious, the above if's are embedded in a for loop that cycles around some JTextFields. Full code at: http://pastebin.ca/2199327
Why not simpler :
public static String regexpluschar = "^\\+[\\w <]";
public static String regexpluspluschar = "^\\+{2}[\\w <]";
public static String regexpluspluspluschar = "^\\+{3}[\\w <]";
or even
public static String regexpluschar = "^\\+[^\\+]";
public static String regexpluspluschar = "^\\+{2}[^\\+]";
public static String regexpluspluspluschar = "^\\+{3}[^\\+]";
Edit : It's working on my test program, but I had to removed your specific code :
String toChange = getItem(i);
setItemFiltered(i, toChange);
proof : my output is :
Filtering 3 +s.
+++Adam is working very well. is in the 3 + filter.
Filtering 2 +s.
++Adam is working well. is in the 2 + filter.
Filtering 1 +.
+Adam is doing OK. is in the 1 + filter.
Your filter is working, but you specific code may not... (maybe have a look at setItemFiltered?)
I was thinking something like this would be easier:
public static void main(String[] args) {
Pattern pattern = Pattern.compile("^(\\+{1,3}).*");
Matcher matcher = pattern.matcher(<your text>);
if (matcher.matches()) {
String pluses = matcher.group(1);
switch (pluses.length()) {
}
}
}
And if you want to be sure that ++++This is insane does not match then change the pattern to
Pattern pattern = Pattern.compile("^(\\+{1,3})[^+].*");