How to remove line feed and carriage retun from string


#1

i have a piston pulling weather alerts from weather underground and storing in a variable. i can grab the alert message, however there seems to be some "invisible " line feeds or returns that are being populated in that variable.

how to i strip the result to just text and not the line feeds?


#2

Screenshot?


#3

Robin. I am gathering the alert message from my custom device handler. A better weather. It allows me to change weather info based on zip code rather than hub location. The attribute is set up as a string. It polls weather underground fro an alert message and then saves the message to the attribute alertMessage.

If I populate the variable as seen in screen shot it has something in it causing a line feed and sonos balks at it.

However if I copy and past the same info into a variable directly it works flawlessly with sonos. Reads it all out.

Notice the variables are different color. The brown works the green does not

This is live logs from ide for the one rom pulling the info from device handler

And this one from the copy and paste


#4

Same info. Different method. Seems to balk at the first / in the string. I’m thinking there is a line feed right before it.

Tried replace(string,’ /‘) and it won’t do it. But if I do replace(string,’/‘) it removes the / but leaves the “invisible” character there

Unfortunelatey I can’t test this using $weather.alerts.alertmessage right now as I don’t have any weather alerts at my hub location right now


#5

Try changing variable type to dynamic instead of string.


#6

Also, paste the text into the expression editor instead of value field, does it force new lines there?

If it does, highlight the text and you might see "<br />" which (without my selection of raw formatting in this post) would be invisible in a browser but forces a new line.


#7

I can’t seem to figure that test out. Sorry. But let’s assume they are there. Is there a way to remove them?


#8

Perhaps use:

replace("variableName", '<br />', '')

But the br’s would copy paste and exist in the in your copied version as well as the original, so probably not relevant.


#9

Well crud. This is driving me Nuts. There are definitely line breaks in there. If you look at the ide logs. The one that errors out has definite line feeds in it compared to the other one.

Here is my groovy code for getting that info from the device handler. Any help would be appreciated with this.

 def alerts = get("alerts")?.alerts      
def alertType = "[${alerts?.type[0]}]"
def newKeys = alerts?.collect{it.type + it.date_epoch} ?: []
//log.trace device.currentState("alertKeys")
def oldKeys = device.currentState("alertKeys")?.jsonValue
def noneString = "There Are No Current Weather Alerts"
if (!newKeys && oldKeys == null) {
 	send(name: "alertKeys", value: newKeys.encodeAsJSON(), displayed: false)
    send(name: "alert", value: noneString, descriptionText: "${device.displayName} has no current weather alerts", isStateChange: true, displayed: false)
    }
else if (newKeys != oldKeys) {
 	if (oldKeys == null) {
    	oldKeys = []
        }
        send(name: "alertKeys", value: newKeys.encodeAsJSON(), displayed: false)
       	def newAlerts = false
       	alerts.each {alert ->
       		if (!oldKeys.contains(alert.type + alert.date_epoch)) {
             	def msg = "${alert.description} from ${alert.date} until ${alert.expires}"
               	//send(name: "alert", value: pad(alert.description), descriptionText: msg, isStateChange: true)
                send(name: "alertMessage",value: "${alert.message}",displayed: true)
                sendEvent(name:"alert", value:"${alertType}", displayed: false)
                newAlerts = true
            	}
        }

	if (!newAlerts && device.currentValue("alert") != noneString) {
        send(name: "alert", value: noneString, descriptionText: "${device.displayName} has no current weather alerts", isStateChange: true, displayed: false)
        send(name:"alertMessage",value:"", displayed: false)
    	}
	}
}
else {
    log.warn "No response from Weather Underground API"
 	}
}

#10

Try pasting in word and inspect the hidden characters… worth a shot. You can try a replace() on that copied character.


#11

How about replace(test_text_from_weather_underground, '/[\\s\\r\\n]+/', ' ') which will replace any run of whitespace (spaces, tabs, line breaks) with a single space?

TIL that unlike every other regex implementation I have seen, \s does not seem to include line breaks in webCoRE… the \\r\\n in that expression should not be included, but without them at least in the evaluation console line breaks are not replaced. Maybe a groovy thing, but not according to groovy docs?


#12

It’s the \s. That is being put in there. I tried without the \n and \r and it works as expected. Weird part though, is when I has the statement as @ipaterson shared. It remove all the letters ‘r’ and ‘n’ from the text. The s’s Stayed either way now speak text command to sonos doesn’t error out and it plays the message.

THANK YOU! :beer:


#13

Hm those are supposed to represent \s any whitespace character, \r carriage return, and \n line feed rather than the letters s r and n. The webCoRE expression evaluator requires an extra backslash in the patterns for me but I didn’t try it in a piston. Glad that it’s working for you!


#14

For whatever reason weather underground alert messages have that character in the message. If you try to send that directly to sonos speaker via the speak text command it won’t play and errors out in ide logs.

Once I applied the replace \s to the response from weather underground, it plays the message without errors. My goal is to check for storm warnings and then play them via sonos notifications You can base them on storm keys for underground to play them for only on user defined alerts that you want… ie okay thunderstorm warnings but not fog warnings

Here is the working speak part of the piston. That’s all I built till I could get it to play message first


#15

And for those that may want to try it?
Mind you I am using my custom device handler. ‘A better weather’ to gather info I need to simplify.

I just need to add set volume level to this. However in testing, I don’t want to wake family ], as they are all in bed right now.


#16

I’m using A Better Weather to turn on/ off a virtual switch that is tied into my thermostat, but it does not seem to update as quick as the accuweather but I like it because its more accurate. Is there a way to adjust the frequency that is updates or refreshes?


#17

You can go into the better weather device on mobile app and click the gear in upper right corner and select how often to update and it will give you options

Or you can send a poll command to it and it will update from a piston

NOTE: it only updates the information that weather underground is providing. If they don’t update it fast enough for what you need it won’t make a difference.


#18

Duh! Thanks I just did not see that for some reason.