Let's start by saying I have a very large project, part of this project is to grab a user recovery action status, and a user email, and send it through a service layer back to the front end of the application. The catch is, the email needs to be altered on the back end so it doesn't get sent plain text. What I mean by this is, when the value gets populated on the back end, I need to have some code to modify it so it will have a format like this: j*****e#domain.com. This absolutely needs to be done in the method that I'm working on(which honestly isn't very big). Here is the method I have that will grab the status from another method within the same class, as well as grabbing the email of the user:
public CredentialRecoveryResponse RecoveryResponse(CredentialRecoveryRequest request)
{
CredentialRecoveryResponse response = new CredentialRecoveryResponse();
response.Status = RecoverCredentials(request);
if (response.Status == UserRecoveryActionStatus.Success)
{
User usr = UserRepository.GetByID(request.UserID);
response.Email = usr.EmailAddress;
}
return response;
}
Somehow, inside this method, I need to take that usr.EmailAddress and modify it do "block" or change the values to "*" for all characters except the first and last characters before the "#domain.com" portion. Is there a quick and easy way to do this within the method that way the whole email address isn't getting sent back through the wire?
Here's one take:
private static string ObfuscateEmail(string email)
{
return Regex.Replace(email, "^(?<name>[^#]+)", m => {
string match = m.Groups["name"].Value;
return match[0] + new String('*', match.Length - 1);
});
}
What is this doing?
The method uses Regex.Replace and passes a lambda function to do the actual replacement
The regex pattern simply says match everything to the left of the # sign and create a named group called 'name'.
The lambda function then takes the first character of the match and appends to it a series of asterisks, using an overload of the String method (char, int) which repeats that char N number of times. It's N-1 here since the first char is unobfuscated.
Related
I have a textfield controller which matches a RegExp whenever the user type it in. For example the typed in string may be "#jack and #jill went up the hill". The following code will match the taghandles and list them.
Firstly the TextField:
TextField(
controller: myController,
)
Which listens for each input into the text field and passes it to a function:
myController.addListener(_matchTextToRegexp);
The function then matches taghandles ie. '#jack' '#jill'
_matchTextToRegexp() {
String value = myController.text;
RegExp regExpTaghandle = RegExp(r"\B#+([\w]+)\b");
Iterable matches = regExpTaghandle.allMatches(value);
matches.forEach((match) {
tagHandle = value.substring(match.start, match.end);
_callToAction(tagHandle);
}
}
The issue is that i want to call a function _callToAction() and pass it the taghandle (for example it could pass the substring/taghandle to a typeahead suggestion dropdown menu as the user types it in - similar functionality to a tweet mention). This code works for one taghandle, but if the users continues inputting text (or adds multiple taghandles) into the form it will keep matching the first taghandle even though the user has typed passed the first taghandle.
So how do you distinguish between multiple taghandles as they are dynamically typed in?
I'm currently using a not-very-Scala-like approach to parse large Unix mailbox files. I'm still learning the language and would like to challenge myself to find a better way, however, I do not believe I have a solid grasp on just what can be done with an Iterator and how to effectively use it.
I'm currently using org.apache.james.mime4j, and I use the org.apache.james.mime4j.mboxiterator.MboxIterator to get a java.util.Iterator from a file, as so:
// registers an implementation of a ContentHandler that
// allows me to construct an object representing an email
// using callbacks
val handler: ContentHandler = new MyHandler();
// creates a parser that parses a SINGLE email from a given InputStream
val parser: MimeStreamParser = new MimeStreamParser(configBuilder.build());
// register my handler
parser.setContentHandler(handler);
// Get a java.util.Iterator
val iterator = MboxIterator.fromFile(fileName).build();
// For each email, process it using above Handler
iterator.forEach(p => parser.parse(p.asInputStream(Charsets.UTF_8)))
From my understanding, the Scala Iterator is much more robust, and probably a lot more capable of handling something like this, especially because I won't always be able to fit the full file in memory.
I need to construct my own version of the MboxIterator. I dug through the source for MboxIterator and was able to find a good RegEx pattern to use to determine the beginning of individual email messages with, however, I'm drawing a blank from now on.
I created the RegEx like so:
val MESSAGE_START = Pattern.compile(FromLinePatterns.DEFAULT, Pattern.MULTILINE);
What I want to do (based on what I know so far):
Build a FileInputStream from an MBOX file.
Use Iterator.continually(stream.read()) to read through the stream
Use .takeWhile() to continue to read until the end of the stream
Chunk the Stream using something like MESSAGE_START.matcher(someString).find(), or use it to find the indexes the separate the message
Read the chunks created, or read the bits in between the indexes created
I feel like I should be able to use map(), find(), filter() and collect() to accomplish this, but I'm getting thrown off by the fact that they only give me Ints to work with.
How would I accomplish this?
EDIT:
After doing some more thinking on the subject, I thought of another way to describe what I think I need to do:
I need to keep reading from the stream until I get a string that matches my RegEx
Maybe group the previously read bytes?
Send it off to be processed somewhere
Remove it from the scope somehow so it doesn't get grouped the next time I run into a match
Continue to read the stream until I find the next match.
Profit???
EDIT 2:
I think I'm getting closer. Using a method like this gets me an iterator of iterators. However, there are two issues: 1. Is this a waste of memory? Does this mean everything gets read into memory? 2. I still need to figure out a way to split by the match, but still include it in the iterator returned.
def split[T](iter: Iterator[T])(breakOn: T => Boolean):
Iterator[Iterator[T]] =
new Iterator[Iterator[T]] {
def hasNext = iter.hasNext
def next = {
val cur = iter.takeWhile(!breakOn(_))
iter.dropWhile(breakOn)
cur
}
}.withFilter(l => l.nonEmpty)
If I understand correctly, you want to lazily chunk a large file delimited by a regex recognizable pattern.
You could try to return an Iterator for each request but the correct iterator management would not be trivial.
I'd be inclined to hide all file and iterator management from the client.
class MBox(filePath :String) {
private val file = io.Source.fromFile(filePath)
private val itr = file.getLines().buffered
private val header = "From .+ \\d{4}".r //adjust to taste
def next() :Option[String] =
if (itr.hasNext) {
val sb = new StringBuilder()
sb.append(itr.next() + "\n")
while (itr.hasNext && !header.matches(itr.head))
sb.append(itr.next() + "\n")
Some(sb.mkString)
} else {
file.close()
None
}
}
testing:
val mbox = new MBox("so.txt")
mbox.next()
//res0: Option[String] =
//Some(From MAILER-DAEMON Fri Jul 8 12:08:34 2011
//some text AAA
//some text BBB
//)
mbox.next()
//res1: Option[String] =
//Some(From MAILER-DAEMON Mon Jun 8 12:18:34 2012
//small text
//)
mbox.next()
//res2: Option[String] =
//Some(From MAILER-DAEMON Tue Jan 8 11:18:14 2013
//some text CCC
//some text DDD
//)
mbox.next() //res3: Option[String] = None
There is only one Iterator per open file and only the safe methods are invoked on it. The file text is realized (loaded) only on request and the client gets just what's requested, if available. Instead of all lines in one long String you could return each line as part of a collection, Seq[String], if that's more applicable.
UPDATE: This can be modified for easy iteration.
class MBox(filePath :String) extends Iterator[String] {
private val file = io.Source.fromFile(filePath)
private val itr = file.getLines().buffered
private val header = "From .+ \\d{4}".r //adjust to taste
def next() :String = {
val sb = new StringBuilder()
sb.append(itr.next() + "\n")
while (itr.hasNext && !header.matches(itr.head))
sb.append(itr.next() + "\n")
sb.mkString
}
def hasNext: Boolean =
if (itr.hasNext) true else {file.close(); false}
}
Now you can .foreach(), .map(), .flatMap(), etc. But you can also do dangerous things like .toList which will load the entire file.
I need to send a custom email message to every User of a list ( List < User > ) I have. (I'm using C# .NET)
What I would need to do is to replace all the expressions (that start with "[?&=" have "variableName" in the middle and then ends with "]") with the actual User property value.
So for example if I have a text like this:
"Hello, [?&=Name]. A gift will be sent to [?&=Address], [?&=Zipcode], [?&=Country].
If [?&=Email] is not your email address, please contact us."
I would like to get this for the user:
"Hello, Mary. A gift will be sent to Boulevard Spain 918, 11300, Uruguay.
If marytech#gmail.com is not your email address, please contact us."
Is there a practical and clean way to do this with Regex?
This is a good place to apply regex.
The regular expression you want looks like this /\[\?&=(\w*)\]/ example
You will need to do a replace on the input string using a method that allows you to use a custom function for replacement values. Then inside that function use the first capture value as the Key so to say and pull the correct corresponding value.
Since you did not specify what language you are using I will be nice and give you an example in C# and JS that I made for my own projects just recently.
Pseudo-Code
Loop through matches
Key is in first capture group
Check if replacements dict/obj/db/... has value for the Key
if Yes, return Value
else return ""
C#
email = Regex.Replace(email, #"\[\?&=(\w*)\]",
match => //match contains a Key & Replacements dict has value for that key
match?.Groups[1].Value != null
&& replacements.ContainsKey(match.Groups[1].Value)
? replacements[match.Groups[1].Value]
: "");
JS
var content = text.replace(/\[\?&=(\w*)\]/g,
function (match, p1) {
return replacements[p1] || "";
});
I have integrated oAuth2 (Facebook, LinkedIn, etc) with my XPages app to allow for authentication to easily add comments (response docs). When a user authenticates, it has to redirect to the facebook/linkedin page, then return to complete the document creation. I use the state variable to do this, and pass it in the querystring of the url. When the page reloads and sees the state variable, it calls a "beforePageLoad" event and creates the response document if the user authenticated and has the correct state document.
My problem is when there is already a state parameter in the querystring. I want to replace the value, not add it to the end. I use a solution here from stackOverflow by ellemayo called updateQueryStringParameter. When I call it from my beforePageLoads it runs, but never replaces the parameter, it only appends it to the end. I end up with ...&state=E5A&state=E5F
I have a feeling that it is in the line,
return uri.replace(re, '$1' + key + "=" + value + '$2');
I can write the code using #ReplaceSubstring(), etc, but want to know if there are problems running regex in XPages SSJS. I read on Lotus.com that
A Regular Expression can be specified as Server-side, which uses the
Java (java.util.regex) API or Client-side, which uses the browser
JavaScript Regular Expression Engine. Client-side and Server-side
Regular Expression syntax is similar, but there are differences that a
user must be aware of.
Should I avoid regex in XPages SSJS ? I have it working extensively in client and in some field validations on the XPage itself.
Here is the call to the function:
if(#Contains( qString,"state=")){
qString=updateQueryStringParameter(qString, "state", linkDoc.getNoteID() );
}else{
qString="?"+qString+"&state=" + linkDoc.getNoteID()
}
the function:
function updateQueryStringParameter(uri, key, value) {
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf('?') !== -1 ? "&" : "?";
if (uri.match(re)) {
// I also tried --> if (re.test(uri)) {
return uri.replace(re, '$1' + key + "=" + value + '$2');
}
else {
return uri + separator + key + "=" + value;
}
}
It was not an XPage or Regex problem. I was using the querystring provided by Domino the excludes the "?" as part of the querystring. when I send "?" + qString to the function, it works. Regex needed to know where to start looking, thus it never found the start of the query string.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How do I linkify text using ActionScript 3
I have this script that grabs a twitter feed and displays in a little widget. What I want to do is look at the text for a url and convert that url to a link.
public class Main extends MovieClip
{
private var twitterXML:XML; // This holds the xml data
public function Main()
{
// This is Untold Entertainment's Twitter id. Did you grab yours?
var myTwitterID= "username";
// Fire the loadTwitterXML method, passing it the url to your Twitter info:
loadTwitterXML("http://twitter.com/statuses/user_timeline/" + myTwitterID + ".xml");
}
private function loadTwitterXML(URL:String):void
{
var urlLoader:URLLoader = new URLLoader();
// When all the junk has been pulled in from the url, we'll fire finishedLoadingXML:
urlLoader.addEventListener(Event.COMPLETE, finishLoadingXML);
urlLoader.load(new URLRequest(URL));
}
private function finishLoadingXML(e:Event = null):void
{
// All the junk has been pulled in from the xml! Hooray!
// Remove the eventListener as a bit of housecleaning:
e.target.removeEventListener(Event.COMPLETE, finishLoadingXML);
// Populate the xml object with the xml data:
twitterXML = new XML(e.target.data);
showTwitterStatus();
}
private function addTextToField(text:String,field:TextField):void{
/*Regular expressions for replacement, g: replace all, i: no lower/upper case difference
Finds all strings starting with "http://", followed by any number of characters
niether space nor new line.*/
var reg:RegExp=/(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig;
//Replaces Note: "$&" stands for the replaced string.
text.replace(reg,"$&");
field.htmlText=text;
}
private function showTwitterStatus():void
{
// Uncomment this line if you want to see all the fun stuff Twitter sends you:
//trace(twitterXML);
// Prep the text field to hold our latest Twitter update:
twitter_txt.wordWrap = true;
twitter_txt.autoSize = TextFieldAutoSize.LEFT;
// Populate the text field with the first element in the status.text nodes:
addTextToField(twitterXML.status.text[0], twitter_txt);
}
If this
/(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig
is your regexp for converting text to urls, than i have some remarks.
First of all, almost all characters in chacacter classes are parsed literally.
So, here
[-A-Z0-9+&##\/%?=~_|!:,.;]
you say to search any of this characters (except /).
Simple regexp for url search will look similar to this
/\s((https?|ftp|file):\/\/)?([-a-z0-9_.:])+(\?[-a-z0-9%_?&.])?(\s+|$)/ig
I'm not sure, if it will process url borders right, but \b symbol can be a dot, so i think \s (space or linebreak) will suit better.
I`m not sure about ending (is it allowed in actionscript to use end-of-string symbol not at the end of regexp?)
And, of course, you have to tune it to suit your data.