illegal text block open delimiter sequence, missing line terminator - java

Java 13 is coming, so I started studying its new features, one of which is text blocks.
I wrote a simple program
public final class Example {
public static void main(String[] args) {
final String greeting = """Hello
It's me, Andrew!""";
System.out.println(greeting);
}
}
I was expecting to see
Hello
It's me, Andrew!
What I got is a compilation error saying
illegal text block open delimiter sequence, missing line terminator

The context of your text block must start from a new line.
public final class Example {
public static void main(String[] args) {
final String greeting = """
Hello
It's me, Andrew!""";
System.out.println(greeting);
}
}
prints
Hello
It's me, Andrew!
An excerpt from JEP 355: Text Blocks (Preview):
A text block consists of zero or more content characters, enclosed by opening and closing delimiters.
The opening delimiter is a sequence of three double quote characters (""") followed by zero or more white spaces followed by a line terminator. The content begins at the first character after the line terminator of the opening delimiter.
You don't necessarily have to put a line terminator at the end of your content, though.
The closing delimiter is a sequence of three double quote characters. The content ends at the last character before the first double quote of the closing delimiter.
final String greeting = """
Hello
It's me, Andrew!
""";
would mean
Hello
It's me, Andrew!
<an empty line here>
I find it extremely unclear, so I had to share this with the community.

For the record, a rationale for the decision not to allow content immediately after """ is given here
The reason for this is that text blocks are primarily designed to support multi-line strings, and requiring the initial line terminator simplifies the indentation handling rules

Related

Android \n newline is escaped in textview

I have echo $result in PHP code and I am printing the result to a textview and I want to display it in multiline but I get this in the textView
Available articles: 28
---------------------------------------
number of clients: 23
Top solded Articles and its beneficient:
Muffin Mix - Lemon Cranberry:161.41
Mushrooms - Black, Dried:148.62
Amaretto:134.01
Longos - Grilled Veg Sandwiches:122.89
Here is my android code
public void processFinish(String output) {
TextView reprttxt = (TextView)findViewById(R.id.reprttxt);
output.replace("\\n",System.getProperty("line.separator"));
reprttxt.setText(output);
}
Notice that I tried output.replace("\\n",System.getProperty("line.separator")); and output.replace("\\\n",System.getProperty("line.separator")); but it doesn't work. How to solve that by modifying the Android Java code or the PHP code?
Use a CharSquence instead of a String for output. TextView.setText() doesn't like String text that contains special characters it will either strip it or display it weirdly depending on the circumstance CharSquence doesn't have this problem.
According to this doc you have to set a property like android:maxLines="2". You can set any value you like. Then '\n' should work as you expected.
The string doesn't have a real embedded newline '\n' character. It has a "\\n" substring- an actual backslash followed by an n. The correct way to fix this is by fixing the server- it shouldn't be sending the data like this. If you need a hack, replace "\\n", not "\n"
You can tell this is the case by the fact a \n is in the actual output. If it was just the wrong type of separator, it would either be whitespace or ignored instead. BTW, on Android the line separator is '\n' as it is on all Linux based systems.
public void processFinish(String output) {
TextView reprttxt = (TextView)findViewById(R.id.reprttxt);
reprttxt.setText(Html.fromHtml(output));
}
example : output = "this is \n two line";

Replace repeated xml tags value using regex

Input -
String ipXmlString = "<root>"
+ "<accntNoGrp><accntNo>1234567</accntNo></accntNoGrp>"
+ "<accntNoGrp><accntNo>6663823</accntNo></accntNoGrp>"
+ "</root>";
Tried follwing things using to mask values within using
String op = ipXmlString .replaceAll("<accntNo>(.+?)</accntNo>", "######");
But above code masks all the values
<root><accntNoGrp>######</accntNoGrp><accntNoGrp>######</accntNoGrp></root>
Expected Output:
<root><accntNoGrp><accntNo>#####67</accntNo></accntNoGrp><accntNoGrp><accntNo>#####23</accntNo></accntNoGrp></root>
How to achieve this using java regex ?Could someone help
Your replacement is wrong, you need to include the <accntNo> tag in the actual replacement. Also, it appears that you want to show the last two characters/numbers of the account number. In this case, we can capture this information during the match and use it in the replacement.
Code:
String op = ipXmlString.replaceAll("<accntNo>(?:.+?)(.{2})</accntNo>", "<accntNo>######$1</accntNo>");
Explanation:
<accntNo> match an opening tag
(?:.+?) match, but do not capture, anything up until the first
(.{2}) two characters before closing tag (and capture this)
</accntNo> match a closing tag
Note here that by using ?: inside a parenthesis in the pattern, we tell the regex engine to not capture it. There is no point in capturing anything before the last two characters of the account number because we don't want to us it.
The $1 quantity in the replacement refers to the first capture group. In this case, it is the last two characters of the account number. Hence, we build the replacement string you want this way.
Demo here:
Rextester
Try this code:
public static void main(String[] args) {
String ipXmlString = "<root>"
+ "<accntNoGrp><accntNo>1234567</accntNo></accntNoGrp>"
+ "<accntNoGrp><accntNo>6663823</accntNo></accntNoGrp>"
+ "</root>";
String replaceAll = ipXmlString.replaceAll("\\d+", "######");
System.out.println(replaceAll);
}
Prints:
<root><accntNoGrp><accntNo>######</accntNo></accntNoGrp><accntNoGrp><accntNo>######</accntNo></accntNoGrp></root>

Escape special characters using Regex in java [duplicate]

Does Java have a built-in way to escape arbitrary text so that it can be included in a regular expression? For example, if my users enter "$5", I'd like to match that exactly rather than a "5" after the end of input.
Since Java 1.5, yes:
Pattern.quote("$5");
Difference between Pattern.quote and Matcher.quoteReplacement was not clear to me before I saw following example
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
It may be too late to respond, but you can also use Pattern.LITERAL, which would ignore all special characters while formatting:
Pattern.compile(textToFormat, Pattern.LITERAL);
I think what you're after is \Q$5\E. Also see Pattern.quote(s) introduced in Java5.
See Pattern javadoc for details.
First off, if
you use replaceAll()
you DON'T use Matcher.quoteReplacement()
the text to be substituted in includes a $1
it won't put a 1 at the end. It will look at the search regex for the first matching group and sub THAT in. That's what $1, $2 or $3 means in the replacement text: matching groups from the search pattern.
I frequently plug long strings of text into .properties files, then generate email subjects and bodies from those. Indeed, this appears to be the default way to do i18n in Spring Framework. I put XML tags, as placeholders, into the strings and I use replaceAll() to replace the XML tags with the values at runtime.
I ran into an issue where a user input a dollars-and-cents figure, with a dollar sign. replaceAll() choked on it, with the following showing up in a stracktrace:
java.lang.IndexOutOfBoundsException: No group 3
at java.util.regex.Matcher.start(Matcher.java:374)
at java.util.regex.Matcher.appendReplacement(Matcher.java:748)
at java.util.regex.Matcher.replaceAll(Matcher.java:823)
at java.lang.String.replaceAll(String.java:2201)
In this case, the user had entered "$3" somewhere in their input and replaceAll() went looking in the search regex for the third matching group, didn't find one, and puked.
Given:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
replacing
msg = msg.replaceAll("<userInput \\/>", userInput);
with
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
solved the problem. The user could put in any kind of characters, including dollar signs, without issue. It behaved exactly the way you would expect.
To have protected pattern you may replace all symbols with "\\\\", except digits and letters. And after that you can put in that protected pattern your special symbols to make this pattern working not like stupid quoted text, but really like a patten, but your own. Without user special symbols.
public class Test {
public static void main(String[] args) {
String str = "y z (111)";
String p1 = "x x (111)";
String p2 = ".* .* \\(111\\)";
p1 = escapeRE(p1);
p1 = p1.replace("x", ".*");
System.out.println( p1 + "-->" + str.matches(p1) );
//.*\ .*\ \(111\)-->true
System.out.println( p2 + "-->" + str.matches(p2) );
//.* .* \(111\)-->true
}
public static String escapeRE(String str) {
//Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
//return escaper.matcher(str).replaceAll("\\\\$1");
return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1");
}
}
Pattern.quote("blabla") works nicely.
The Pattern.quote() works nicely. It encloses the sentence with the characters "\Q" and "\E", and if it does escape "\Q" and "\E".
However, if you need to do a real regular expression escaping(or custom escaping), you can use this code:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
This method returns: Some/\s/wText*/\,**
Code for example and tests:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
^(Negation) symbol is used to match something that is not in the character group.
This is the link to Regular Expressions
Here is the image info about negation:

Java - SecurityException in Method "printDuplicates"

I'm a newcomer to Java trying to submit a working project, in this instance printDuplicates. The instructions are as follows:
Write a method named printDuplicates that accepts as its parameter a Scanner for an input file containing a series of lines. Your method should examine each line looking for consecutive occurrences of the same token on the same line and print each duplicated token along how many times it appears consecutively. Non-repeated tokens are not printed. Repetition across multiple lines (such as if a line ends with a given token and the next line starts with the same token) is not considered in this problem.
For example, if the input file contains the following text:
hello how how are you you you you
I I I am Jack's Jack's smirking smirking smirking smirking smirking revenge
bow wow wow yippee yippee yo yippee yippee yay yay yay
one fish two fish red fish blue fish
It's the Muppet Show, wakka wakka wakka
Your method would produce the following output for the preceding input file:
how*2 you*4
I*3 Jack's*2 smirking*5
wow*2 yippee*2 yippee*2 yay*3
wakka*3
Your code prints only the repeated tokens; the ones that only appear once in a row are not shown. Your code should place a single space between each reported duplicate token and should respect the line breaks in the original file. This is why a blank line appears in the expected output, corresponding to the fourth line of the file that did not contain any consecutively duplicated tokens. You may assume that each line of the file contains at least 1 token of input.
Here is my code, pretty much ready for submitting.
import java.io.*;
import java.util.*;
Scanner input;
public static void printDuplicates(Scanner input) throws Exception {
String word = "";
String word2 = "";
input = new Scanner(new File("idontknowwhattodo.txt"));
while(input.hasNextLine()) {
Scanner line = new Scanner(input.nextLine());
int repeat = 1;
word = line.next();
while(line.hasNext()) {
word2 = line.next();
while(word.equals(word2)) {
repeat++;
if(line.hasNext()){
word2 = line.next();
} else {
break;
}
}
if(repeat!=1) {
System.out.print(word + "*" + repeat + " ");
}
repeat = 1;
word = word2;
}
System.out.println();
}
}
However, whenever I try to submit my project, it throws back this error:
(no output was produced!)
SecurityException on line 5:
You are not allowed to read the file /usr/share/tomcat7/temp/idontknowwhattodo.txt
java.lang.SecurityException: You are not allowed to read the file /usr/share/tomcat7/temp/idontknowwhattodo.txt
at java.io.FileInputStream.<init>(FileInputStream.java:135)
at java.io.FileReader.<init>(FileReader.java:72)
at Scanner.<init>(Scanner.java:330)
at printDuplicates (Line 5)
What does this mean? I have multiple working projects but I can't seem to submit them due to this one error. Any experts that can help me on this one? Thank you.
It looks like you are using Tomcat from your path. Tomcat requires special security permission to read or write files. This is a basic protection to prevent malicious code from accessing sensitive files on the OS. You can configure these directories or stick to reading and writing to the default ones:
https://tomcat.apache.org/tomcat-7.0-doc/security-manager-howto.html
Unable to add a comment because of reputation points so using the Answers section.
Agree with above comments, it is related to permissions.
Do an ls -ltr on /usr/share/tomcat7/temp/idontknowwhattodo.txt
Check whether the user (say myuser) with which you are running you java application has necessary permissions for /usr/share/tomcat7/temp/idontknowwhattodo.txt.
Two options below:
Give the user "myuser" the necessary permissions to the idontknowwhattodo.txt using chmod.
Or copy idontknowwhattodo.txt to a location where "myuser" has the permissions.
Problem description says that you're getting Scanner object as parameter. You don't have to recreate it, you're probably trying to submit your project to some online competition. Program on the server will load your class and call the method printDuplicates() with Scanner object as parameter, you don't have to worry about how it gets created. Just use it, and everything would be fine.
Just comment the scanner assignment line as below
String word = "";
String word2 = "";
/*input = new Scanner(new File("idontknowwhattodo.txt"));*/
while(input.hasNextLine()) {
...
As per instructions, you are already getting the Scanner object(which references the input file) as parameter to your method. So, you should not be re-initializing it.
This line should be removed:
input = new Scanner(new File("idontknowwhattodo.txt"));

java printf help needed

public class Format
{
public static void main(String args[])
{
System.out.printf("%30s|%30s","Organization","Number of users");
System.out.printf("%30s|%30s","Arcot","100");
}
}
It prints:
Organization| Number of users Arcot| 100
Why is the 2nd row out of alignment? The word "Arcot" is not given enough padding, although the word "100" is. I'm sorry, this text window applies its own formatting, it is not showing what I have pasted as the output. You may need to run the code to see the output obtained.
Try these.
System.out.println(String.format("%30s|%30s","Organization","Number of users"));
System.out.println(String.format("%30s|%30s","Arcot","100"));
System.out.printf("%30s|%30s\n","Organization","Number of users");
System.out.printf("%30s|%30s\n","Arcot","100");
You have to insert \n issue a newline character end of first parameter of printf.
More info about using escape character.
This works as expected:
System.out.printf("%30s|%30s%n","Organization","Number of users");
System.out.printf("%30s|%30s%n","Arcot","100");
results in
Organization| Number of users
Arcot| 100
on my machine. You didn't add line feeds. %n is the preferred notation in format Strings.

Categories

Resources