Regular Expression in Java for UMASK - java

I need a Java regular expression to get the following two values:
the value of the UMASK parameter in file /etc/default/security should be set to 077. [Current value: 022] [AA.1.9.3]
the value of UMASK should be set to 077 in /etc/skel/.profile [AA.1.9.3]
I need to get the file name from the input string, as well as the current value if existing.
I wrote a regex as .* (.*?/.*?) (?:\\[Current value\\: (\\d+)\\])?.* for this one, it can match both strings, also to get the file name, but can NOT get the current value.
Then another regex: .* (.*?/.*?) (?:\\[Current value\\: (\\d+)\\])? .* comparing with the first one, there is a space before the last .* for this one, it can match the string 1, and get file name and current value, but it can NOT match the string 2...
What how can I correct these regular expressions to obtain the values described above?

If I understand your requisites correctly (file name and current octal permissions value), you can use the following Pattern:
String input =
"Value for parameter UMASK in file /etc/default/security should be set to 077. " +
"[Current value: 022] [AA.1.9.3] - " +
"Value of UMASK should be set to 077 in /etc/skel/.profile [AA.1.9.3]";
// | "file " marker
// | | group 1: the file path
// | | | space after
// | | || any characters
// | | || | escaped square bracket
// | | || | | "Current value: " marker
// | | || | | | group 2:
// | | || | | | digits for value
// | | || | | | | closing bracket
Pattern p = Pattern.compile("file (.+?) .+?\\[Current value: (\\d+)\\]");
Matcher m = p.matcher(input);
// iterates, but will find only once in this instance (which is desirable)
while (m.find()) {
System.out.printf("File: %s%nCurrent value: %s%n", m.group(1), m.group(2));
}
Output
File: /etc/default/security
Current value: 022

Related

Is there a way of checking for multiple string sequences with String.matches in Java?

I want to look for any of the following sequences: either one of * - / + followed by a * + /
for example:
4+*2 is something I am looking for.
4+5/2 is not
if (combinedArray.matches("[-*+/][*+/]"))
{
...code
}
I'd be happy to know what I did wrong.
I basicly want it to have the same logic as this:
if (combinedArray.contains("*/") | combinedArray.contains("*+") | combinedArray.contains("**")
| combinedArray.contains("//") | combinedArray.contains("/+") | combinedArray.contains("/*")
| combinedArray.contains("+/") | combinedArray.contains("++") | combinedArray.contains("+*")
| combinedArray.contains("-/") | combinedArray.contains("-+") | combinedArray.contains("-*") )
~~~

Scala - how to format a collection into a String?

I'm trying to parse Metrics data into a formatted String so that there is a header and each record below starts from a new line. Initially I wanted to get something close to a table formatting like this:
Id | Name | Rate | Value
1L | Name1 | 1 | value_1
2L | Name2 | 2 | value_2
3L | Name3 | 3 | value_3
But my current implementation results in the following Error:
java.util.MissingFormatArgumentException: Format specifier '%-70s'
What should I change in my code to get it formatted correctly?
import spark.implicits._
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._
case class BaseMetric(val id: Long,
val name: String,
val rate: String,
val value: String,
val count: Long,
val isValid: Boolean
) {
def makeCustomMetric: String = Seq(id, name, rate, value).mkString("\t")
}
val metric1 = new BaseMetric(1L, "Name1", "1", "value_1", 10L, true)
val metric2 = new BaseMetric(2L, "Name2", "2", "value_2", 20L, false)
val metric3 = new BaseMetric(3L, "Name3", "3", "value_3", 30L, true)
val metrics = Seq(metric1, metric1, metric1)
def formatMetrics(metrics: Seq[BaseMetric]): String = {
val pattern = "%-50s | %-70s | %-55s | %-65s | %f"
val formattedMetrics: String = pattern.format(metrics.map(_.makeCustomMetric))
.mkString("Id | Name | Rate | Value\n", "\n", "\nId | Name | Rate | Value")
formattedMetrics
}
val metricsString = formatMetrics(metrics)
The specific error is due to the fact that you pass a Seq[String] to format which expects Any*. You only pass one parameter instead of five. The error says it doesn't find an argument for your second format string.
You want to apply the pattern on every metric, not all the metrics on the pattern.
The paddings in the format string are too big for what you want to achieve.
val pattern = "%-2s | %-5s | %-4s | %-6s"
metrics.map(m => pattern.format(m.makeCustomMetric: _*))
.mkString("Id | Name | Rate | Value\n", "\n", "\nId | Name | Rate | Value")
The _* tells the compiler that you want to pass a list as variable length argument.
makeCustomMetric should return only the List then, instead of a string.
def makeCustomMetric: String = Seq(id, name, rate, value)
Scala string interpolation is the optimized way to concat/foramt strings.
Reference: https://docs.scala-lang.org/overviews/core/string-interpolation.html
s"id: $id ,name: $name ,rate: $rate ,value: $value ,count: $count, isValid: $isValid"

Match text between empty lines

I have a text in following blocks:
AAAAAAA
BBBBBBB
CCCCCCC
DDDDDD. YYYYYYYYYYYYYYYYYYYYYY
EEEEE 1234567890
Some random text
Some text random
Random text
Text
Some random text
ZZZZZZZZZZZZZZZZ
UUUUUUUUUUUUUUUU
How to select with regexp a following block?
Some random text
Some text random
Random text
Text
Some random text
From the original text I know that this block goes after line DDDDDD. YYYYYYYYYYYYYYYYYYYYYY which is optionally followed by line EEEEE 1234567890 and also that block is between lines that contain only \s symbols.
I have tried pattern DDDDDD.*\\s+(.*)\\s+ it doesn't work.
You can use the following Pattern to match your expected text:
String text = "AAAAAAA\nBBBBBBB\nCCCCCCC\n\nDDDDDD. YYYYYYYYYYYYYYYYYYYYYY "
+ "\nEEEEE 1234567890 "
+ "\n\nSome random text\nSome text random\nRandom text\nText \nSome random text\n\n"
+ "ZZZZZZZZZZZZZZZZ\nUUUUUUUUUUUUUUUU";
Pattern p = Pattern.compile(
// | 6 "D"s
// | | actual dot
// | | | some whitespace
// | | | | 22 "Y"s
// | | | | | more whitespace
// | | | | | | optional:
// | | | | | || 5 "E"s
// | | | | | || | whitespace
// | | | | | || | | 10 digits
// | | | | | || | | | more whitespace including line breaks
// | | | | | || | | | | your text
// | | | | | || | | | | | followed by any "Z" sequence
"D{6}\\.\\s+Y{22}\\s+(E{5}\\s\\d{10}\\s+)?(.+?)(?=Z+)",
Pattern.DOTALL
);
Matcher m = p.matcher(text);
if (m.find()) {
System.out.println(m.group(2));
}
Output
Some random text
Some text random
Random text
Text
Some random text
Note
Not sure how to delimit the final part, so I just used a capitalized Z sequence (1+).
Up to you to refine.

Regex doesn't work in Java

I have some expected pattern for data that I receive in my server. The following 2 lines are expected as I wish.
¬14AAAA3170008#¶
%AAAA3170010082¶
So, to check if the data it's fine, I wrote the following regex:
(?<pacote>\\A¬\\d{2}[a-fA-F0-9]{4}\\d{7}.{2})
(?<pacote>\\A[$%][a-fA-F0-9]{4}\\d{10}.)
And it works fine in regex101.com but Java Pattern and Matcher doesn't understand this regex as expected. Here goes my Java code
String data= "¬14AAAA3170008#¶%AAAA3170010082¶";
Pattern patternData = Pattern.compile( "(?<pacote>\\A¬\\d{2}[a-fA-F0-9]{4}\\d{7}.{2})", Pattern.UNICODE_CASE );
Matcher matcherData = patternData.matcher( data );
if( matcherData .matches() ){
System.out.println( "KNOW. DATA[" + matcherData .group( "pacote" ) + "]");
}else{
System.out.println( "UNKNOW" );
}
And it didn't worked as expected. Could someone help me figure what mistake I'm doing?
You're using Matcher#matches, which matches the whole input.
However, the Pattern you're using only applies for the first input, and your whole input contains the two cases concatenated.
On top of that, the \\A boundary matcher implies the pattern follows the start of the input.
You can use the following pattern to generalize and match the two:
String test = "¬14AAAA3170008#¶%AAAA3170010082¶";
Pattern p = Pattern.compile(
// | named group definition
// | | actual pattern
// | | | ¬ + 2 digits or $%
// | | | | 4 hex alnums
// | | | | | 7 to 10 digits
// | | | | | | any 1 or 2 characters
// | | | | | | | multiple times (2 here)
"(?<pacote>((¬\\d{2}|[$%])[a-fA-F0-9]{4}\\d{7,10}.{1,2})+)"
);
Matcher m = p.matcher(test);
if (m.find()) {
System.out.println(m.group("pacote"));
}
Output
¬14AAAA3170008#¶%AAAA3170010082¶

Setting up a Regex Pattern in Java

I am having some difficulty trying to create a working regex pattern for recognizing a string of file names.
Pattern pattern = Pattern.compile("(\\w+)(\\.)(t)(x)(t)(\\s$|\\,)");
When using a .find() from a matcher class on my sample input, say
"file1.txt,file2.txt "
I am returned true, which is fine, however other erroneous input also returns true.
This erroneous input includes strings such as:
"file1.txt,,file2.txt "
"file%.text "
I have been consulting this website as I have been trying to construct them, I'm pretty sure I am missing something rather obvious though. Link
To validate your file name list, you can use the following solution:
// | preceded by start of input, or
// | | comma, preceded itself by either word or space
// | | | file name
// | | | | dot
// | | | | | extension
// | | | | | | optional 1 space
// | | | | | | | followed by end of input
// | | | | | | | | or comma,
// | | | | | | | | followed itself by word character
Pattern pattern = Pattern.compile("(?<=^|(?<=[\\w\\s]),)(\\w+)(\\.)txt\\s?(?=$|,(?=\\w))");
String input = "file1.txt,file2.txt";
String badInput = "file3.txt,,file4.txt";
String otherBadInput = "file%.txt, file!.txt";
Matcher m = pattern.matcher(input);
while (m.find()) {
// printing group 1: file name
System.out.println(m.group(1));
}
m = pattern.matcher(badInput);
// won't find anything
while (m.find()) {
// printing group 1: file name
System.out.println(m.group(1));
}
m = pattern.matcher(otherBadInput);
// won't find anything
while (m.find()) {
// printing group 1: file name
System.out.println(m.group(1));
}
Output
file1
file2
May this help you:
Pattern pattern = Pattern.compile("(.*?\\.\\w+)(?:,|$)");
String files = "file1.txt,file2.txt";
Matcher mFile = pattern.matcher(files);
while (mFile.find()) {
System.out.println("file: " + mFile.group(1));
}
Output:
file: file1.txt
file: file2.txt
With only .txt files: (.*?\\.txt)(?:,|$)
Naive way :
public boolean validateFileName(String string){
String[] fileNames= string.split(",");
Pattern pattern = Pattern.compile("\b[\w]*[.](txt)\b"); /*match complete name, not just pattern*/
for(int i=0;i<fileNames.length;i++){
Matcher m = p.matcher(fileNames[i]);
if (!m.matches())
return false;
}
return true;
}
Pattern p = Pattern.compile("((\\w+\\.txt)(,??|$))+");
The above Pattern lets "file1.txt,,file2.txt" pass, but does not get an empty file for the two commas.
The other Strings "file1.txt,file2.txt" and "file%txt" are processed correctly.

Categories