I have string like this abc+def(ghi)+jkl and I want to get {abc,ghi,jkl} as the result of regex. So far I found: [a-z]+(?!\\() but it returns {abc,de,ghi,jkl}. Does anyone know how to write proper regular expression?
Examples:
var + var_s => { var, var_s }
var + method(arg) + var_s => { var, arg, var_s }
string * string_s + method_name(arg,arg_s) => { string, string_s, arg, arg_s }
var + 2 * ( 3 + something ) +count( 3, gender ) => { var, something, gender }
I need to take all strings consist of 'a-z A-z _' but not ending with ( char. Strings: method(, method_name(, count( should be omitted because of ( .
if (preg_match('/(\w+)/i', $subject, $regs)) {
$result = $regs[0];
} else {
$result = "";
}
(\w+)
Options: case insensitive
Match the regular expression below and capture its match into backreference number 1 «(\w+)»
Match a single character that is a “word character” (letters, digits, and underscores) «\w+»
Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
(regexbuddy is your friend!)
I have found a solution on http://msdn.microsoft.com/en-us/library/az24scfc.aspx:
\b[a-zA-Z_]+(?!\()\b
if (preg_match('/\b([a-z]+)(?!\(|\))\b/i', $subject, $regs)) {
$result = $regs[0];
} else {
$result = "";
}
Related
The following lines of code
String query ="MATCH (n) WHERE n.name =~ '(?i).*SUBSTRING.*' RETURN n";
final PreparedStatement statement = connection.prepareStatement(query);
will change the query String
"MATCH (n) WHERE n.name =~ '(?i).*SUBSTRING.*' RETURN n"
in the prepareStatement (by using replacePlaceholders method )
to "MATCH (n) WHERE n.name =~ '({1}i).*SUBSTRING.*' RETURN n"
means it replace ? by {1}
How to prevent the change of (?i) and to not become ({1}i) when passed to prepareStatement() and have always (?i) even if we pass via replacePlaceholders regex?
Below I give more info of the problem:
The same task that would perform as LIKE clause in Cypher queries is made by the following construct:
MATCH (n) where n.Name =~ '.*SUBSTRING.*' return n.Name, n;
and to make it case insensitive:
MATCH (n) WHERE n.name =~ '(?i).*SUBSTRING.*' RETURN n;
And by using neo4j-jdbc-3.5.1.jar
The org.neo4j.jdbc.Neo4jPreparedStatement.java
/**
* Default constructor with connection and statement.
*
* #param connection The JDBC connection
* #param rawStatement The prepared statement
*/
protected Neo4jPreparedStatement(Neo4jConnection connection, String rawStatement) {
super(connection);
this.statement = PreparedStatementBuilder.replacePlaceholders(rawStatement);//<----LINE X
this.parametersNumber = PreparedStatementBuilder.namedParameterCount(statement);
this.parameters = new HashMap<>(this.parametersNumber);
this.batchParameters = new ArrayList<>();
}
And in org.neo4j.jdbc.utils.PreparedStatementBuilder
/**
* This method return a String that is the original raw string with all valid placeholders replaced with neo4j curly brackets notation for parameters.
* <br>
* i.e. MATCH n RETURN n WHERE n.name = ? is transformed in MATCH n RETURN n WHERE n.name = {1}
*
* #param raw The string to be translated.
* #return The string with the placeholders replaced.
*/
public static String replacePlaceholders(String raw) {
int index = 1;
String digested = raw;
String regex = "\\?(?=[^\"]*(?:\"[^\"]*\"[^\"]*)*$)";
Matcher matcher = Pattern.compile(regex).matcher(digested);
while (matcher.find()) {
digested = digested.replaceFirst(regex, "{" + index + "}");
index++;
}
return digested;
}
In replacePlaceholders() the ? is transformed to {1}.
This sounds like a bug to me, the Neo4J drivers seems to unconditionally replace question marks with the Neo4J parameter placeholder (in this case inside a string literal), instead of only replacing where a parameter can occur syntactically. You should report this to Neo4J.
The workaround would seem to me to use a parameter here, and set your regular expression as the value of that parameter.
That is, use
"MATCH (n) WHERE n.name =~ ? RETURN n"
And use stmt.setString(1, "(?i).*SUBSTRING.*") to set the expression for that variable on the prepared statement.
Or as you suggested yourself in the comments, use:
"MATCH (n) WHERE lower('n.name') contains lower(SUBSTRING) RETURN n"
I want extract from a table all rows where in a column (string) there is at least one word that starts with a specified character.
Example:
Row 1: 'this is the first row'
Row 2: 'this is th second row'
Row 3: 'this is the third row'
If the specified character is T -> I would extract all 3 rows
If the specified character is S -> I would extract only the second column
...
Please help me
Assuming you mean "space delimited sequence of characters, or begin to space or space to end" by "word", then you can split on the delimiter and test them for matches:
var src = new[] {
"this is the first row",
"this is th second row",
"this is the third row"
};
var findChar = 'S';
var lowerFindChar = findChar.ToLower();
var matches = src.Where(s => s.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Any(w => w.ToLower()[0] == lowerFindChar));
The LINQ Enumerable.Any method tests a sequence to see if any element matches, so you can split each string into a sequence of words and see if any word begins with the desired letter, compensating for case.
Try this:
rows.Where(r => Regex.IsMatch(r, " [Tt]"))
You can replace the Tt with Ss (both assuming you want either upper case or lower case).
The problem of course is, what is a "word"?
Is the character sequence 'word' in the sentence above a word according to your definition? It doesn't start with a space, not even a white-space.
A definition of a word could be:
Define wordCharacter: something like A-Z, a-z.
Define word:
- the non-empty sequence of wordCharacters at the beginning of a string followed by a non-wordcharacter
- or the non-empty sequence of wordCharacters at the end of a string preceded by a non-wordcharacter
- any non-empty sequence of wordCharacters in the string preceded and followed by a non-wordcharacter
Define start of word: the first character of a word.
String: "Some strange characters: 'A', 9, äll, B9 C$ X?
- Words: Some, strange characters, A
- Not Words: 9, äll, B9, C$ X?
So you first have to specify precisely what you mean by word, then you can define functions.
I'll write it as an extension method of IEnumerable<string>. Usage will look similar to LINQ. See Extension Methods Demystified
bool IsWordCharacter(char c) {... TODO: implement your definition of word character}
static IEnumerable<string> SplitIntoWords(this string text)
{
// TODO: exception if text null
if (text.Length == 0) return
int startIndex = 0;
while (startIndex != text.Length)
{ // not at end of string. Find the beginning of the next word:
while (startIndex < text.Length && !IsWordCharacter(text[startIndex]))
{
++startIndex;
}
// now startIndex points to the first character of the next word
// or to the end of the text
if (startIndex != text.Length)
{ // found the beginning of a word.
// the first character after the word is either the first non-word character,
// or the end of the string
int indexAfterWord = startWordIndex + 1;
while (indexAfterWord < text.Length && IsWordCharacter(text[indexAfterWord]))
{
++indexAfterWord;
}
// all characters from startIndex to indexAfterWord-1 are word characters
// so all characters between startIndexWord and indexAfterWord-1 are a word
int wordLength = indexAfterWord - startIndexWord;
yield return text.SubString(startIndexWord, wordLength);
}
}
}
Now that you've got a procedure to split any string into your definition of words, your query will be simple:
IEnumerabl<string> texts = ...
char specifiedChar = 'T';
// keep only those texts that have at least one word that starts with specifiedChar:
var textsWithWordThatStartsWithSpecifiedChar = texts
// split the text into words
// keep only the words that start with specifiedChar
// if there is such a word: keep the text
.Where(text => text.SplitIntoWords()
.Where(word => word.Length > 0 && word[0] == specifiedChar)
.Any());
var yourChar = "s";
var texts = new List<string> {
"this is the first row",
"this is th second row",
"this is the third row"
};
var result = texts.Where(p => p.StartsWith(yourChar) || p.Contains(" " + yourChar));
EDITED:
Alternative way (I'm not sure it works in linq query)
var result = texts.Where(p => (" " + p).Contains(" " + yourChar));
you can use .ToLower() if you want Case-insensitive check.
I have grouped a number followed by a letter by this regex:
(\d*)(\D)
when number exist, result is:
[12,letter]
when there is not number, result is:
["",letter]
how can i put something instead of an empty string?
Like this:
(\d*|put "1")(\D)
Can Regex do anything of similar?
You can write your own matching function.
function matchPut(regexp, str) {
var match = str.match(regexp);
if(match[1] === "") {
match[1] = "1";
}
return match;
}
result = matchPut(/(\d*)(\D)/,"L");
console.log(result);
Using LINQ how can I transform only the first letter of s.Password to lowercase
if (s.Password == password){}
i want that the first char of s.Password will be in lower case,
i tried :
if( s.Password[0].toString().toLower() + s.Password(1) ) == password ){}
If you would like to make a decision based on an item's position in LINQ, you can use Select that takes a Func with two parameters - the item and its index:
var pwd = "BadPassword";
var res = new string(
pwd.Select((c, i) => i==0 ? char.ToLower(c) : c).ToArray()
); // produces badPassword
The functor above converts the initial character at i==0 to lower case, while leaving all other characters in place.
Demo 1.
Note: LINQ is not necessary for this conversion. You can do the same thing in one line by using Substring:
var res = char.ToLower(pwd[0]) + pwd.Substring(1);
Demo 2.
Given a random alphanumeric string (A-Z0-9) between 1 to 10 characters long, I'd like to insert a hyphen when it changes from alpha to numeric, or numeric to alpha.
I have something that works now, but I'm sure it performs as awful as it looks. I know there's a better way to handle this, but someone in the office made weak coffee this morning, or at least that's the excuse I'm going with. ;)
I have to do this ~15 million times, so the faster, the better.
Code snip:
my #letters = split //, $string;
my $type;
foreach my $letter ( #letters ) {
if (! $type) {
if ($letter =~ /^[A-Z]$/) {
$type = 'a'
}
else {
$type = 'd'
}
$string = $letter;
next;
}
else {
if ($type eq 'a') {
if ($letter =~ /^[0-9]$/) {
$string .= '-' . $letter;
$type = 'd';
next;
}
else {
$sring .= $letter;
}
}
else {
if ($letter =~ /^[A-Z]$/) {
etc, etc.
Ugh, it hurts just looking at that.
This should work:
$string =~ s/([A-Z])([0-9])/$1-$2/g;
$string =~ s/([0-9])([A-Z])/$1-$2/g;
Add the /i modifier if you want to to be case-insensitive.
Probably faster (since it avoids captures), but requires 5.10:
$string =~ s/[A-Z]\K(?=[0-9])/-/g;
$string =~ s/[0-9]\K(?=[A-Z])/-/g;