I created a method to validate a JTextField. When I am typing any alphabet character it should automatically convert into uppercase character, but I am not getting an uppercase.
How to solve this problem, when using evt.consume()?
Code snippet:
public void PRJ_TEXT_VALIDATION(JTextField PTxt, int PTxtLen, String POptnStr, KeyEvent Pevt){
String TmpStr=PTxt.getText();
char TmpChar=Pevt.getKeyChar();
//TmpChar=Character.toUpperCase(TmpChar);
if ((TmpStr.trim().length() + 1) <= PTxtLen){
if (POptnStr == "INTEGER") {
if (!((TmpChar>='0') && (TmpChar<='9'))){
Pevt.consume();
}
} else if (POptnStr == "NUMERIC"){
if(!((TmpChar>= '0' && TmpChar <= '9') || (TmpChar == '.'))){
Pevt.consume();
}
} else if (POptnStr == "ALPHABET"){
if(!(TmpChar>= 'a' && TmpChar <= 'z' || TmpChar >= 'A' && TmpChar <='Z')){
Pevt.consume();
}
} else if (POptnStr == "PHONE"){
if (!((TmpChar>= '0' && TmpChar <= '9') || (TmpChar == '-')||
(TmpChar == '+')||(TmpChar == '(')||(TmpChar == ')'))){
Pevt.consume();
}
}
}else{
Pevt.consume();
}
}
Use document filter to achieve this.
You can find usage in DocumentFilter that maps lowercase letters to uppercase.
Related
This question already has answers here:
What is a NumberFormatException and how can I fix it?
(9 answers)
Closed 2 years ago.
When I try to use the function to iterate the user input expression, I get the java.lang.NumberFormatException, I try fixing the loop much time, but I still cannot understand where did it when wrong. The IDE suggest it went wrong in the parstInt while loop
Here is the code:
import java.util.Scanner;
import java.util.Stack;
static Stack<Integer> stackForOperand = new Stack<Integer>();
static Stack<Character> stackForOperator = new Stack<Character>();
public static int processOneOperator(char stackForOperator, int num1, int num2) {
int result = 0;
switch (stackForOperator) {
case '+':
result = num1 + num2;
case '-':
result = num1 - num2;
case '*':
result = num1 * num2;
case '/':
if (num2 != 0) {
result = num1 / num2;
} else {
throw new UnsupportedOperationException("divide by zero error");
}
}
return result;
}
public static boolean num_order(char first, char second) {
if (first == '(' || second == ')') {
return false;
} else if ((first == '*' || first == '/') && (second == '+' || second == '-')) {
return false;
} else {
return true;
}
}
public static int calculation_loop(String expression) {
for (int i = 0; i < expression.length(); i++) {
if (expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
String more_num = "";
while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
more_num += expression.charAt(i++);
int more_num2 = Integer.parseInt(more_num);
stackForOperand.push(more_num2);
i--;
}
} else if (expression.charAt(i) == '(') {
stackForOperator.push(expression.charAt(i));
} else if (expression.charAt(i) == ')') {
while (stackForOperator.peek() != '(') {
stackForOperand.push(
processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
stackForOperator.pop();
}
} else if (expression.charAt(i) == '+' || expression.charAt(i) == '-' || expression.charAt(i) == '*'
|| expression.charAt(i) == '/') {
while (!stackForOperator.empty() && num_order(expression.charAt(i), stackForOperator.peek())) {
stackForOperand.push(
processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
stackForOperator.push(expression.charAt(i));
}
}
}
while (!stackForOperator.empty()) {
stackForOperand
.push(processOneOperator(stackForOperator.pop(), stackForOperand.pop(), stackForOperand.pop()));
}
return stackForOperand.pop();
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("/");
String input = scanner.nextLine();
input = input.replaceAll("\\s+", "");
System.out.println(input);
Integer output = calculation_loop(input);
System.out.println(output);
}
}
Looking at this piece of code:
public static int calculation_loop(String expression) {
for (int i = 0; i < expression.length(); i++) {
if (expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
String more_num = "";
while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
more_num += expression.charAt(i++);
int more_num2 = Integer.parseInt(more_num);
stackForOperand.push(more_num2);
i--;
}
So. Suppose having such an expression "2345+6789". According to your code i is incrementing and decrementing before end of while loop.
while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
more_num += expression.charAt(i++);
...
i--;
}
Is this your intention? It makes your loop infinite and it finishes only because number format exception is thrown while parsing. This is why I think your parser throws exception: You got the digit '2' in first place, concatenate it with more_num, then increment the i, after that decrement the i and at the next iteration you have the same previous position with same char '2', then concatenate it again to more_num ad infinitum. And first you parse more_num which is "2", on next iteration you append one more '2' and more_num "22" then "222"... Till it become bigger than type int can hold like "22222222222222222222222" and exception is thrown
Second thing. Suppose you remove i-- and your loop will normally iterate the next char. So, your stackForOperand will push first the number 2, then will push the number 23 then the number 234, then will push the number 2345. Is that your intension? I think more logically is to move Integer.parseInt and stackForOperand.push after the while loop
public static int calculation_loop(String expression) {
for (int i = 0; i < expression.length(); i++) {
if (expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
String more_num = "";
while (i < expression.length() && expression.charAt(i) >= '0' && expression.charAt(i) <= '9') {
more_num += expression.charAt(i++);
}
int more_num2 = Integer.parseInt(more_num);
stackForOperand.push(more_num2);
I would like to evaluate a phone number using the provided method. The phone number should always have a length of 10. However the following method always seems to return false. Why is that? Thanks.
public static boolean valPhoneNumber(String phonenumber){
boolean result= true;
if (phonenumber.length() > 10 || phonenumber.length() < 10){
result= false;
}else
phonenumber.length();
char a=phonenumber.charAt(0);
char b=phonenumber.charAt(1);
char d=phonenumber.charAt(3);
char e=phonenumber.charAt(4);
char f=phonenumber.charAt(5);
if (a<2 || a>9){
result = false;
}else if( b<0 || b>8){
result = false;
}else if (d<2 || d>9){
result = false;
}else if (e==1 && f==1){
result = false;
}
return result;
}
So looking into your ladder which is comparing character to number. In this case the comparison will happen with ASCII value.
You can put single quotes to check the range:
if (a < '2' || a > '9') {
result = false;
} else if( b < '0' || b > '8') {
result = false;
} else if (d < '2' || d > '9') {
result = false;
} else if (e == '1' && f == '1') {
result = false;
}
One liner:
result = !((a < '2' || a > '9') || (b < '0' || b > '8') || (d < '2' || d > '9') || (e == '1' && f == '1'));
I think your code wrong at the parsing phonenumber.charAt(). This always return char, and when you do comparision with integer it will convert to number which present to that char code (ASCII code). I think you should modify your code to int a=Character.getNumericValue(phonenumber.charAt(0)); and so on
I think an approach with regex here would be the cleanest and easiest solution.
public static boolean valPhoneNumber(String phonenumber){
String regex = "[2-9][0-8][0-9][2-9][02-9][0-29][0-9]{4}";
return phonenumber.matches(regex);
}
You should cast the char variables to integer.
you can try this:
int a = Integer.parseInt(phonenumber.substring(0,1));
I added single quotes to check the range. Thank you all.
public static boolean valPhoneNumber(String phonenumber) {
boolean result= true;
if (phonenumber.length() != 10) {
result = false;
} else {
//phonenumber.length();
char a = phonenumber.charAt(0);
char b = phonenumber.charAt(1);
char d = phonenumber.charAt(3);
char e = phonenumber.charAt(4);
char f = phonenumber.charAt(5);
if (a < '2' || a > '9') {
} else if( b<'0' || b>'8') {
result = false;
} else if (d < '2' || d > '9') {
result = false;
} else if (e == '1' && f == '1') {
result = false;
}
}
return result;
}
When the user enters their ID I want it to be in a specific format, they are mostly explained within the comments. I was wondering if their was an easier more efficient way of doing this. Also whether or not there is a way to change the entered letters to capital the way I've done the code, or any other method.
private boolean setCustomerID(String id) {
//Validates the customerID contains 3 letters a hypthen then 4 numbers
if ((id.charAt(0) < 'A' || id.charAt(0) > 'Z')
|| (id.charAt(1) < 'A' || id.charAt(1) > 'Z')
|| (id.charAt(2) < 'A' || id.charAt(2) > 'Z')
|| (id.charAt(3) != '-')
|| !isDigit(id.charAt(4))
|| !isDigit(id.charAt(5))
|| !isDigit(id.charAt(6))
|| !isDigit(id.charAt(7))) {
return false;
//Checks the user enters P, B or C for first letter
} else if ((id.charAt(0) == 'P' || id.charAt(0) == 'B' || id.charAt(0) == 'E')
//Checks the second and third letter are in the correct region
&& ((id.charAt(1) == 'S' && id.charAt(2) == 'C')
|| (id.charAt(1) == 'S' && id.charAt(2) == 'C')
|| (id.charAt(1) == 'W' && id.charAt(2) == 'A')
|| (id.charAt(1) == 'N' && id.charAt(2) == 'I')
|| (id.charAt(1) == 'N' && id.charAt(2) == 'E')
|| (id.charAt(1) == 'N' && id.charAt(2) == 'W')
|| (id.charAt(1) == 'M' && id.charAt(2) == 'I')
|| (id.charAt(1) == 'E' && id.charAt(2) == 'A')
|| (id.charAt(1) == 'S' && id.charAt(2) == 'E')
|| (id.charAt(1) == 'S' && id.charAt(2) == 'W'))){
// SC (Scotland), WA (Wales), NI (Northern Ireland), NE (North-East), NW (North-West),
//MI (Midlands), EA (East Anglia), SE (South-East), SW (South-West).
return true;
}
return false;
}
Use regex.
private boolean matchCustomerID(String id) {
return id.matches("^[PBE](?:SC|WA|NI|NE|NW|MI|EA|SE|SW)-\\d{4}\\b");
}
Regular expressions are one way of solving the problem. You can compose the pattern in a way that makes maintenance easier. Building on rcorreia's pattern, you can do something like:
private boolean setCustomerID(String id) {
char[] validFirstLetters = { 'P', 'B', 'E' };
String[] validRegions = { "SC", "WA", "NI", "NE", "NW", "MI", "EA", "SE", "SW" };
String pattern =
String.format("^[%s](?:%s)-\\d{4}$", new String(validFirstLetters),
String.join("|", validRegions));
return id.matches(pattern);
}
Note that this uses String.join() from Java 8. If you don't use Java 8 yet, consider using StringUtils from Apache Commons Lang.
Regexp is a great feature, but not easy to write and understand..
In this case, I would follow your way, but I would define some testing method. In this manner the code will be readable and easy to write Unit tests for it.
If you need some change later, you will understand the code.
Example:
testForLength();
testForLetters();
testForFirstTwoLetters();
This program is supposed to compare "DNA" strings.
Input:
3
ATGC
TACG
ATGC
CGTA
AGQ
TCF
First line represents how many times the program will be run. Each time it runs, it compares the two strings. A matches with T and vice versa. G matches with C and vise versa. So if the first letter of string 1 is A, the first letter of string 2 should be T. If the next one is T, the next one on the other string should be A and etc. If a letter other than A, T, G, or C appear, it is a bad sample. If its bad, print out bad, if its good, print out good. I tried many different combinations to this and they all worked fine but according the the judge's test data (they have different input), it failed. Does anyone see anything wrong with this? I know it might not be the most efficient way of getting the job done but it did, at least to my understanding.
Output:
GOOD
BAD
BAD
public class DNA
{
public static void main(String[] args) throws IOException
{
Scanner scan = new Scanner (new File ("dna.dat"));
int T = scan.nextInt();
scan.nextLine();
boolean valid = true;
for (int i = 0; i < T; i++)
{
String strand1 = scan.nextLine();
strand1 = strand1.toUpperCase();
String strand2 = scan.nextLine();
strand2 = strand2.toUpperCase();
for (int p = 0; p < strand1.length(); p++)
{
if (strand1.charAt(p) != 'A' && strand1.charAt(p) != 'T' && strand1.charAt(p) != 'G' && strand1.charAt(p) != 'C'
&& strand2.charAt(p) != 'A' && strand2.charAt(p) != 'T' && strand2.charAt(p) != 'G' && strand2.charAt(p) != 'C')
{
valid = false;
break;
}
if (strand1.length() != strand2.length())
{
valid = false;
break;
}
}
if (valid)
{
for (int p = 0; p < strand1.length(); p++)
{
if ((strand1.charAt(p) == 'A' && strand2.charAt(p) == 'T') || (strand1.charAt(p) == 'T' && strand2.charAt(p) == 'A')
|| (strand1.charAt(p) == 'G' && strand2.charAt(p) == 'C') || (strand1.charAt(p) == 'C' && strand2.charAt(p) == 'G'))
valid = true;
else
valid = false;
}
}
if (valid)
out.println("GOOD");
else
out.println("BAD");
valid = true;
}
}
}
I added the toUpperCase and compared the strings for equal length just as a last attempt to see if their data maybe had some lowercase letters or different length strings though they SHOULD all be the same length and uppercase. Nevertheless, the program was still rejected for "failing the judges test data."
You need a break in the second for loop when valid = false. For example if characters 1,2,3 are wrong but #4 is a match you will still end up with valid.
I would convert the strings to arrays to make things easier:
for (int i = 0; i < T; i++)
{
boolean valid = true;
String strand1 = scan.nextLine();
strand1 = strand1.toUpperCase();
String strand2 = scan.nextLine();
strand2 = strand2.toUpperCase();
if ( strand1.length() != strand2.length())
{
valid = false;
}
if (valid) {
char[] c1 = strand1.toCharArray();
char[] c2 = strand2.toCharArray();
for (int p = 0; p < c1.length; p++)
{
if (-1 == "ACTG".indexOf(c1[p]) || -1 == "ACTG".indexOf(c2[p]))
{
valid = false;
break;
}
}
if (valid)
{
for (int p = 0; p < c1.length; p++)
{
if (('A' == c1[p] && 'T' != c2[p]) ||
('T' == c1[p] && 'A' != c2[p]) ||
('C' == c1[p] && 'G' != c2[p]) ||
('G' == c1[p] && 'C' != c2[p])) {
valid = false;
break;
}
}
}
}
if (valid)
System.out.println("GOOD");
else
System.out.println("BAD");
}
Change all
&&
in
if (strand1.charAt(p) != 'A' && strand1.charAt(p) != 'T' && strand1.charAt(p) != 'G' && strand1.charAt(p) != 'C' && strand2.charAt(p) != 'A' && strand2.charAt(p) != 'T' && strand2.charAt(p) != 'G' && strand2.charAt(p) != 'C')
to
||
if ANY, not ALL character is other than A, T, G, or C, then we exit the loop.
Hi
i would like to remove all invalid XML characters from a string.
i would like to use a regular expression with the string.replace method.
like
line.replace(regExp,"");
what is the right regExp to use ?
invalid XML character is everything that is not this :
[#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
thanks.
Java's regex supports supplementary characters, so you can specify those high ranges with two UTF-16 encoded chars.
Here is the pattern for removing characters that are illegal in XML 1.0:
// XML 1.0
// #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
String xml10pattern = "[^"
+ "\u0009\r\n"
+ "\u0020-\uD7FF"
+ "\uE000-\uFFFD"
+ "\ud800\udc00-\udbff\udfff"
+ "]";
Most people will want the XML 1.0 version.
Here is the pattern for removing characters that are illegal in XML 1.1:
// XML 1.1
// [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
String xml11pattern = "[^"
+ "\u0001-\uD7FF"
+ "\uE000-\uFFFD"
+ "\ud800\udc00-\udbff\udfff"
+ "]+";
You will need to use String.replaceAll(...) and not String.replace(...).
String illegal = "Hello, World!\0";
String legal = illegal.replaceAll(pattern, "");
Should we consider surrogate characters? otherwise '(current >= 0x10000) && (current <= 0x10FFFF)' will never be true.
Also tested that the regex way seems slower than the following loop.
if (null == text || text.isEmpty()) {
return text;
}
final int len = text.length();
char current = 0;
int codePoint = 0;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
current = text.charAt(i);
boolean surrogate = false;
if (Character.isHighSurrogate(current)
&& i + 1 < len && Character.isLowSurrogate(text.charAt(i + 1))) {
surrogate = true;
codePoint = text.codePointAt(i++);
} else {
codePoint = current;
}
if ((codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD)
|| ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
|| ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
|| ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF))) {
sb.append(current);
if (surrogate) {
sb.append(text.charAt(i));
}
}
}
All these answers so far only replace the characters themselves. But sometimes an XML document will have invalid XML entity sequences resulting in errors. For example, if you have in your xml, a java xml parser will throw Illegal character entity: expansion character (code 0x2 at ....
Here is a simple java program that can replace those invalid entity sequences.
public final Pattern XML_ENTITY_PATTERN = Pattern.compile("\\&\\#(?:x([0-9a-fA-F]+)|([0-9]+))\\;");
/**
* Remove problematic xml entities from the xml string so that you can parse it with java DOM / SAX libraries.
*/
String getCleanedXml(String xmlString) {
Matcher m = XML_ENTITY_PATTERN.matcher(xmlString);
Set<String> replaceSet = new HashSet<>();
while (m.find()) {
String group = m.group(1);
int val;
if (group != null) {
val = Integer.parseInt(group, 16);
if (isInvalidXmlChar(val)) {
replaceSet.add("&#x" + group + ";");
}
} else if ((group = m.group(2)) != null) {
val = Integer.parseInt(group);
if (isInvalidXmlChar(val)) {
replaceSet.add("&#" + group + ";");
}
}
}
String cleanedXmlString = xmlString;
for (String replacer : replaceSet) {
cleanedXmlString = cleanedXmlString.replaceAll(replacer, "");
}
return cleanedXmlString;
}
private boolean isInvalidXmlChar(int val) {
if (val == 0x9 || val == 0xA || val == 0xD ||
val >= 0x20 && val <= 0xD7FF ||
val >= 0x10000 && val <= 0x10FFFF) {
return false;
}
return true;
}
Jun's solution, simplified. Using StringBuffer#appendCodePoint(int), I need no char current or String#charAt(int). I can tell a surrogate pair by checking if codePoint is greater than 0xFFFF.
(It is not necessary to do the i++, since a low surrogate wouldn't pass the filter. But then one would re-use the code for different code points and it would fail. I prefer programming to hacking.)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
int codePoint = text.codePointAt(i);
if (codePoint > 0xFFFF) {
i++;
}
if ((codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD)
|| ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
|| ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
|| ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF))) {
sb.appendCodePoint(codePoint);
}
}
String xmlData = xmlData.codePoints().filter(c -> isValidXMLChar(c)).collect(StringBuilder::new,
StringBuilder::appendCodePoint, StringBuilder::append).toString();
private boolean isValidXMLChar(int c) {
if((c == 0x9) ||
(c == 0xA) ||
(c == 0xD) ||
((c >= 0x20) && (c <= 0xD7FF)) ||
((c >= 0xE000) && (c <= 0xFFFD)) ||
((c >= 0x10000) && (c <= 0x10FFFF)))
{
return true;
}
return false;
}
From Mark McLaren's Weblog
/**
* This method ensures that the output String has only
* valid XML unicode characters as specified by the
* XML 1.0 standard. For reference, please see
* <a href="http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char">the
* standard</a>. This method will return an empty
* String if the input is null or empty.
*
* #param in The String whose non-valid characters we want to remove.
* #return The in String, stripped of non-valid characters.
*/
public static String stripNonValidXMLCharacters(String in) {
StringBuffer out = new StringBuffer(); // Used to hold the output.
char current; // Used to reference the current character.
if (in == null || ("".equals(in))) return ""; // vacancy test.
for (int i = 0; i < in.length(); i++) {
current = in.charAt(i); // NOTE: No IndexOutOfBoundsException caught here; it should not happen.
if ((current == 0x9) ||
(current == 0xA) ||
(current == 0xD) ||
((current >= 0x20) && (current <= 0xD7FF)) ||
((current >= 0xE000) && (current <= 0xFFFD)) ||
((current >= 0x10000) && (current <= 0x10FFFF)))
out.append(current);
}
return out.toString();
}
From Best way to encode text data for XML in Java?
String xmlEscapeText(String t) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < t.length(); i++){
char c = t.charAt(i);
switch(c){
case '<': sb.append("<"); break;
case '>': sb.append(">"); break;
case '\"': sb.append("""); break;
case '&': sb.append("&"); break;
case '\'': sb.append("'"); break;
default:
if(c>0x7e) {
sb.append("&#"+((int)c)+";");
}else
sb.append(c);
}
}
return sb.toString();
}
If you want to store text elements with the forbidden characters in XML-like form, you can use XPL instead. The dev-kit provides concurrent XPL to XML and XML processing - which means no time cost to the translation from XPL to XML. Or, if you don't need the full power of XML (namespaces), you can just use XPL.
Web Page: HLL XPL
I believe that the following articles may help you.
http://commons.apache.org/lang/api-2.1/org/apache/commons/lang/StringEscapeUtils.html
http://www.javapractices.com/topic/TopicAction.do?Id=96
Shortly, try to use StringEscapeUtils from Jakarta project.