I have a need to convert log messages into JSON, so I decided to write a groovy script to try and accomplish the task. The log messages look like:
InvoiceAdjustment{invoiceAdjustmentId=null, invoiceAdjustmentType='REFUND', invoiceId=20231189, currencyCode='USD', shippingRefundAmount=0.00, shippingRefundAmountUsd=0.00, taxTariffRefundAmount=0.00, taxTariffRefundAmountUsd=0.00, salesTaxTotalRefundAmount=0.00, salesTaxTotalRefundAmountUsd=0.00, vatRefundAmount=0.00, vatRefundAmountUsd=0.00, invoiceAdjustmentItems=[InvoiceAdjustmentItem{invoiceAdjustmentItemId=null, invoiceLineItemId=411729, refundAmount=3.82, refundAmountUsd=3.82, salesTaxRefundAmount=0.00, salesTaxRefundAmountUsd=0.00, returnQuantityExpected=0, returnQuantityActual=0, keptEnrolled=false, cancelShip=true, cancellationSuccessful=true, reshipQuantity=0, relativeLineNumber=4, sku='NTN-CHCK-339CV-NS163880', created=null, createdBy=null}], billingType='BRAINTREE', externalTransactionId='c3rvz7bv', refundTransactionId='null', reason='WAREHOUSE_CANCELLED', reshipmentInvoiceId=null, created=null, createdBy=null, refundedOn=null, notes='Cancelled by warehouse', createdByName='null', createdByEmail='null'}
When iterating through these (using String... args) it appears all single quotes (which I want to key off to know if a field is a string) are gone! For example, the SKU field which is surrounded with single quotes in the input, prints as "sku=NTN-CHCK-339CV-NS163880," -- no quotes!
Is there a way to keep the single quotes from the input so I can replace them in my script?
Here is the script in its entirety:
class LogToJson
{
static void main( String... args )
{
if ( args.length == 0 )
{
println( "Error, you must provide a string." )
}
StringBuilder jsonBuilder = new StringBuilder()
for ( String token : args )
{
if ( token.contains( "{" ) )
{
token = token.contains( "[" ) ? "\"" + token.substring( 0, token.indexOf( '[' ) - 1 ) + "\"=[{"
: "" +
"{\"" + token.substring( token.indexOf( "{" ) + 1, token.indexOf( "=" ) ) + "\"" + token.substring( token.indexOf( "=" ) )
}
else if ( token.contains( '=' ) )
{
token = "\"" + token.substring( 0, token.indexOf( '=' ) ) + "\"" + token.substring( token.indexOf( '=' ) )
}
token = token.replaceAll( '=', ':' ).replaceAll( "\'", "\"" )
jsonBuilder.append( token + ' ' )
}
println( jsonBuilder.toString() )
}
}
Edited to add: It appears if I escape all the single quotes in the input (i.e. replace ' with \' before using it as input) the script works as expected. Ideally, I'd rather not have to do this.
Related
fun printRoom() {
println("Cinema: ")
val rows = 7
val columns = 8
val seats = CharArray(columns) { 'S' }.joinToString { " " }
for (i in 1..rows) {
println("$i" + " " + seats)
}
}
any help will be appreciated. Im sure this is something simple im doing but I can't figure out why this keeps printing commas instead of S's
CharArray.joinToString has these parameters, all of which are optional and have default values:
fun CharArray.joinToString(
separator: CharSequence = ", ",
prefix: CharSequence = "",
postfix: CharSequence = "",
limit: Int = -1,
truncated: CharSequence = "...",
transform: ((Char) -> CharSequence)? = null
): String
joinToString allows you to use your own separator, add your own prefix and postfix, have an optional custom limit on the joining, and have a custom string for when that limit is reached, and also optionally transform the Chars into some other String first, before joining them together.
By passing in { " " }, you pass a lambda expression that simply returns the string " ". This corresponds to the transform parameter. Kotlin thinks that you want to transform every Char to the string " " first, and then join the " " together! Because you didn’t pass the separator parameter, the default value of ”, “ is used as the separator, which is why you see a lot of commas.
What you intended on doing is passing " " as the separator parameter. Don't write a lambda:
val seats = CharArray(columns) { 'S' }.joinToString(" ")
You can also be very explicit about this and say:
val seats = CharArray(columns) { 'S' }.joinToString(separator = " ")
If you don't mind a trailing space, repeat also works:
val seats = "S ".repeat(columns)
Given a string like (2 5). I want to replace multiple spaces with a semi-colon in a string (2 5) in PowerBuilder
Thanks in Advance
This can be done with a regular expression. But the support for regular expression in Powerscript is minimal, you need to use an external COM object like VBScript.RegExp to do something useful.
OLEObject re
int li_retcode
string s
string value
re = Create OLEObject
li_retcode = re.ConnectToNewObject("VBScript.RegExp")
re.Pattern = "\s\s+"
re.Global = True
s = "4 2"
value = re.Replace("4 2" , ";")
MessageBox("", value) // 4;2
re.DisconnectObject()
simply cut out each word, trim and join into a string.
string ls_key = '2 5 8 9'
string ls_new = ''
long ll_pos
do
ll_pos = Pos( ls_key, ' ')
if ll_pos > 0 then
ls_new += trim( left( ls_key, ll_pos - 1) ) + ':'
ls_key = trim( mid( ls_key, ll_pos + 1 ) )
else
ls_new += trim( ls_key )
ls_key = ''
end if
loop while ll_pos > 0
return ls_new
I have a search query which is working in the database client but when using it in nodejs having quotes parsing error.
Here is the original query
match (n)-[l:DATA_FLOWS]->(m) where l.nme =~ '(?i).*new.*' return n, l, m
I'm trying use it in coding.
session.run('match (n)-[l:DATA_FLOWS]->(m) where l.nme =~ ''(?i).*'{feedParam}'.*' return n, l, m', {feedParam:search.value}).then(function (result) {
How to complete the quotes to make it work?
The whole regex has to be passed as parameter :
session.run('match (n)-[l:DATA_FLOWS]->(m) where l.nme =~ ''(?i).*'{feedParam}'.*' return n, l, m', {feedParam:search.value})
.then(...)
Should be changed to :
var regexStr = '(?i).*' + search.value + '.*'
session.run('MATCH (n)-[l:DATA_FLOWS]->(m) WHERE l.nme =~ {feedParam} RETURN n, l, m', {feedParam: regexStr})
.then(...)
** update with more than one parameter ** :
var regexStr = '(?i).*' + search.value + '.*'
var source = 'BoxA'
var destination = 'Box J'
var query = `MATCH (n)-[l:DATA_FLOWS]->(m) WHERE l.nme =~ {feedParam}
AND n.nme = $source AND m.nme = $destination
RETURN n, l, m`
session.run('', {feedParam: regexStr, source: source, destination: destination})
.then(...)
You can concatenate strings with + and you can use ' or " for strings.
So replace ' with '+"'"+'
In your case, you aren't using " so you can just put the string in those
session.run("match (n)-[l:DATA_FLOWS]->(m) where l.nme =~ '(?i).*new.*' return n, l, m", {feedParam:search.value})
This works
let replaced = String(map(aString.generate()) {
$0 == " " ? "-" : $0 })
and this doesn't
let replaced = String(map(aString.generate()) {
$0 == " " ? "" : $0 })
Why?
For Swift 5:
" spaces here ".replacingOccurrences(of: " ", with: "")
returns:
"spaceshere"
Enumerating a string gives a sequence of characters, so $0 inside
the closure has the type Character. This compiles
{ $0 == " " ? "-" : $0 }
because "-" in this context is interpreted as a character literal
and therefore of the same type as $0. But
{ $0 == " " ? "" : $0 }
does not compile because "" is not a character literal (and in the conditional expression a ? b : c the operands b and c
must have the same type).
You can fix that by converting $0 to a string:
{ $0 == " " ? "" : String($0) }
but now the mapping returns an array of strings instead
of an array of characters. So instead
of the String() constructor you have to join the results:
let replaced = "".join(map(aString) { $0 == " " ? "" : String($0) })
// Swift 2 / Xcode 7:
let replaced = "".join(aString.characters.map({ $0 == " " ? "" : String($0) }))
(Note that calling generate() explicitly is not needed.)
Of course the same result would also be achieved with
// Before Swift 3.0
let replaced = aString.stringByReplacingOccurrencesOfString(" ", withString: "")
// After Swift 3.0
let replaced = aString.replacingOccurrences(of: " ", with: "")
If you want to remove white space from string then just pass string with stringByReplacingOccurrencesOfString function like below,
let replacedString = string.replacingOccurrences(of: " ", with: "")
For Text Fields, you can apply directly object of UITextField,
let replacedString = textField.text!.replacingOccurrences(of: " ", with: "")
This should work as of Swift 2.2:
let replaced = String(aString.characters.filter {$0 != " "})
If you want to delete whitespaces before and after a string, which is very useful in user input forms, you can use:
let replaced = aString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
You can apply it directly on a textfield as well.
If you want to remove all whitespaces anywhere in the String I did come up with this solution for Swift 3.0:
let number = "+000 000 000"
let nonWhiteCharacters = number.unicodeScalars.filter {
false == NSCharacterSet.whitespacesAndNewlines.contains($0)
}.map(Character.init)
let whitespacelessNumber = String(nonWhiteCharacters)
or even better (you will need generic extension on Sequence):
extension Sequence {
public func reduce<Result>(_ result: (Self) throws -> Result) rethrows -> Result {
return try result(self)
}
}
and then you can write:
let whitespacelessNumber = number.unicodeScalars.filter {
false == NSCharacterSet.whitespacesAndNewlines.contains($0)
}.map(Character.init).reduce { String($0) }
where you can also replace NSCharacterSet.whitespacesAndNewlines for any of other character sets:
NSCharacterSet.controlCharacters
NSCharacterSet.whitespaces
NSCharacterSet.whitespacesAndNewlines
NSCharacterSet.decimalDigits
NSCharacterSet.letters
NSCharacterSet.lowercaseLetters
NSCharacterSet.uppercaseLetters
NSCharacterSet.nonBaseCharacters
NSCharacterSet.alphanumerics
NSCharacterSet.decomposables
NSCharacterSet.illegalCharacters
NSCharacterSet.punctuationCharacters
NSCharacterSet.capitalizedLetters
NSCharacterSet.symbols
NSCharacterSet.newline
You are mapping thus the number of elements should be preserved. In the second case you remove elements. Your example will fail even in case you replace " " with --.
You might prefer using filter:
let replaced = String(filter(aString.generate()) { $0 != " "})
None of the previous answers where Swifty enough for me, so I ended up with this using Swift 5:
let nonWhitespaceString = String(whitespaceString.compactMap({ $0.isWhitespace ? nil : $0 })
try this one:
let strArray0 = strArray1.map { $0.stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet()) }
Hope this helps
In Swift 3.0 DO as
func RemoveWhiteSpace(aString:String) -> String
{
let replaced = aString.trimmingCharacters(in: NSCharacterSet.whitespaces)
return replaced
}
And use like this
let nonWhiteSpaceStr = self.RemoveWhiteSpace(aString: "I have white Space ")
NOTE: juhan_h's answer on this question is a more succinct version if whitespace is really all you're interested in stripping out.
https://stackoverflow.com/a/57425783/5946596
Swift 5.5
All the answers are great for removing spaces but sometimes I want to remove any whitespaces and newLines throwing in _ and - ... who knows.
The following extension on string lets me do that.
extension String {
func removingCharacters(_ characters:CharacterSet) -> Self {
Self(self.unicodeScalars.filter {
!characters.contains($0)
})
}
func removingCharacters(in string:String) -> Self {
Self(self.unicodeScalars.filter {
!CharacterSet(charactersIn:string).contains($0)
})
}
func replacingCharacters(_ characters:CharacterSet, with newChar:Character) -> Self {
String(self.compactMap( {
CharacterSet(charactersIn: "\($0)").isSubset(of: characters)
? newChar : $0
}))
}
func replacingCharacters(in string:String, with newChar:Character) -> Self {
String(self.compactMap( {
CharacterSet(charactersIn: "\($0)").isSubset(of: CharacterSet(charactersIn:string))
? newChar : $0
}))
}
}
usage:
print("hello \n my name\t is Joe".removingCharacters(.whitespacesAndNewlines))
print("hello \n my name\t is Joe".removingCharacters(in: " \t\n"))
print("ban annan anann ana".replacingCharacters(.whitespacesAndNewlines, with: "_"))
print("ban-annan anann ana".replacingCharacters(in: " -", with: "_"))
Obviously for just spaces the .replacingOccurrences(of: " ", with: "") is better.
I have not done a performance comparison to the
let toArray = aString.components(separatedBy: characterSet)
let backToString = toArray.joined(separator: "+")
style done in Ramis's extension on this question:
https://stackoverflow.com/a/33120336/5946596
I'd be interested if someone does.
See also replacing emojis: https://stackoverflow.com/a/63416058/5946596
I have basically something such as :
var escape = function ( x ) {
if ( ! x ) return '\\N';
return '"' + x.replace( /\r\n/g, '\n' ) + '"';
};
array.forEach( function ( item ) {
process.stdout.write( 'foo:' + [ a, b, d ].map( escape ).join( '\t' ) + '\n' );
item.child.forEach( function ( sub ) {
process.stdout.write( 'bar:' + [ e, f, g ].map( escape ).join( '\t' ) + '\n' );
} );
} );
However, the output file contains, at apparently random locations, strings such as :
bar:\N "1981258" "Can't Get N^#^#^#^#^#^#^#^#^#^#Her Bones In Thefoo:"1981259" "164264"
bar:\N ^# Left" \N \N
bar:^#^#^# \N
It does not make sense for me, since the program should not be able to print anything without wrapping it into double quotes.
I think it's a Node.js bug, due to this line, but I just want to know if there is a workaround.
b^#^#^#^#^#^#^#^#^#x 1 root root 1,5G 17 d\303\251c. 19:14 /D/Release.cs
You don't have to escape crlf sequences.
$ node
> var crlf = '\n';
undefined
> process.stdout.write( 'foo:' + crlf + 'bar:');
foo:
bar:true
> process.stdout.write( 'foo:' + crlf + 'bar:' + crlf + '\\n' + 'foobar?');
foo:
bar:
\nfoobar?true
>
(The "true" at the end of both line is the return value from process.stdout.write in the REPL)
That said, could you post a gist with a sample input and more code (I don't know what a, b, d, e, f, g,... refer to).
Also, depending on your input (and seeing your output), it may make more sense for you to use Buffers instead of raw strings.
It was probably an issue related to the filesystem were the file was wrote (vmhgfs). The second generated file did not have this garbage.