I am currently using a regular expression to find some data in a given string.I wish to find the position of the matching pattern in the string.
Is it possible to find the offset of a Regex in a given string with FreePascal ?
In current versions there are two regex functions. One is only in newer versions, but is the most commonly used one (Sorokin's regexpr). And older unit regex is faster but more limited iirc.
I don't use regular expressions much, so I don't have example syntax for you. There is some information here in the wiki http://wiki.freepascal.org/Regexpr though
Of course you could also try to create a header for the perl pcre library. (or recycle a Delphi one)
However to find the offset a simple substring, one can use the standard POS() function. THere is a replace function too.
Here is an example using the standard RegExpr unit.
{$APPTYPE CONSOLE}
{$IFDEF FPC}{$MODE DELPHI}{$ENDIF}
uses
regexpr;
var
s: string;
e: TRegExpr;
begin
s := 'abcdefg';
e := TRegExpr.Create;
e.Expression := '[c-f]+';
e.Exec(s);
WriteLn(e.Match[0]); // cdef
WriteLn(e.MatchPos[0]); // 3
WriteLn(e.MatchLen[0]); // 4
e.Free;
ReadLn;
end.
Related
Here I get an warning Warning: Implicit string type conversion from "AnsiString" to "UnicodeString"
....
{$mode DelphiUnicode}
{$H+}
....
Function THeader.ToHtml(Constref input: String): String;
Begin
Result := Format('<h%d>%s</h%d>', [FLevel, Chunk(input), FLevel]); // <--- HERE !
End;
My project settings include -MDelphiUnicode. My Lazarus version is 2.2.2.
As I understand it means that if Chunk() returns symbols outside of ASCII (Unicode), then the Result will be problematic. Right? What to do with this warning? Sure, I can cast the Format() result to String. But why is it required? I see that Format's prototype is:
// somewhere in the sysstrh.inc ...
Function Format (Const Fmt : String; const Args : Array of const) : String;
so it already returns a String (which is magically UnicodeString in my case, as I think). What is the problem actually here? And how to work in the correct way with such library functions like Format() (for instance, GetOptionValue() of TCustomApplication)?
ps. I read FreePascal Wiki about Unicode and String types, but I still cannot understand the reason of this warning :)
There are multiple reasons to do so.
The exact codepage of ansistring is under control of the RTL, which can query the OS for it, without the compiler knowing the details. In Lazarus applications this is generally set to utf8, but the compiler doesn't know that.
So calling a ansistring format() could corrupt strings, and repeated conversions are of course also not ideal for a performance.
delphiunicode is a work in progress, and I would not recommend using it (yet) out of habit, only if you really know what you are doing (and by that I mean knowing the state of it in FPC, not that it works in Delphi)
The original plan was to migrate to unicodestring fully, but since Windows now allows UTF8 as native 1-byte codepage (see thick in application tab of project options), the progress on that migration is glacial.
In short, consider arranging your code as much as possible so that string type doesn't matter, and then use utf8 ansistrings in Lazarus for unicode.
Or ignore the warnings, or disable them with some -vn parameter that allows you to disable specific hints/warnings
So I'm just starting to learn Eiffel. One of the first exercises in the book I'm using says to make a function that does base^exp without using ^. I've copied my code below.
class
APPLICATION
inherit
ARGUMENTS
create
make
feature {NONE} -- Initialization
make
-- Run application.
do
create power(2;3)
printf("2 to the power of 3 is " + answer)
end
power(base : REAL; exp : INTEGER) : REAL
-- computers base raised to the bower of exp without using ^
local
remain : INTEGER
do
remain := exp
if remain = 0 then
result := 1
else
from
until
remain = 0
loop
result := result * result
remain := remain -1
end
end
end
end
How do I use this? Do I need it on the same level as feature{NONE}'s make? I know how I'm calling it is wrong, and I can't find anything in the chapter I just read, or online on how to pass parameters into it or how to use it's results.
There are several issues with the original code:
create is used to create an object, but you are not going to create anything, but to get a result of a computation of the function power by calling it. Therefore the keyword create is not needed.
You are using an entity answer to report the result of evaluation on a screen. However it is not declared anywhere. I believe the proper place would be a local variable declaration section.
The entity answer is not initialized to the result of the function power. This is usually done by an assignment instruction.
Feature arguments are separated by a comma, not by a semicolon.
From the original code it's unclear what is the type of the variable answer. Assuming it matches the type of the function power, before adding it to a string, it needs to be converted to a string. This is done by calling the feature out.
The standard feature for printing a string to a console is print, not printf.
Combining the critical points above, we get
make
-- Run application.
local
answer: REAL
do
answer := power(2, 3)
print ("2 to the power of 3 is " + answer.out)
end
After that the code can be compiled. Now less critical points:
It is a good style to put features to a dedicated feature clauses, so I would add a line like feature -- Basic operations before the feature power.
The implementation of the feature power has at least two problems. I'm not going to detail them here, but would give two hints instead:
by default numeric Result is initialized to 0, this needs to be taken into account for operations that use it without first assigning any other value
even though an argument base is passed to the function power it remains unused in the original version of the code
I am trying to search a string from a specific point onward.
I'm looking for a r ether low case or upper case then finding the dash after the r's location. I can do this in php but in ActionScript 3 string.search always starts at the beginning of the string. Is there an alternative that works more like stripos in ActionScript 3?
indexOf optionally takes the offset within the "haystack" as an argument, and except for the case-insensitive nature of stripos it will do what stripos does. You can make indexOf case-insensitive by using toLowerCase on both the "needle" and the "haystack". Using the variable names as found in the stripos documentation that should give something like:
var position:int = haystack.toLowerCase().indexOf(needle.toLowerCase(),offset);
I'm looking around to encode/cast/convert a string into numbers within a query. Like ASCII() but it only returns the left-most character to its relative code. Is there any function or method available on this topic? -which is actually decode-able
JUST For example:
METHOD("test-string") # Outputs: 25478596325417
This will work for strings up to 8 characters long.
To encode:
SELECT CONV(HEX(string), 16, 10);
To decode:
SELECT UNHEX(CONV(number, 10, 16));
MySQL supports integers up to 64 bit long, and this method uses 8 bits per character. Therefore using this method you can store up to 64 / 8 = 8 characters in an integer.
If hexadecimal is good enough for your application, then then function hex() does what you want. For instance, you can try:
select hex('abc'), hex('abcd')
This will work on arbitrary strings. If this doesn't quite work, then perhaps there is a way to convert the hex representation to something appropriate.
By the way, unhex() will return the original string.
You could use
COMPRESS('ABC)
To get a binary string that is not the string. It can compress an arbitrary size. But it is not clear what you are going to do with the number -- or how you need to store it.
Try this one.
SELECT CAST(HEX(your_string) AS DECIMAL);
I admit, I didn't test it, but it should work.
EDIT:
Some other databases (e.g. Oracle, DB2, PostgreSQL) have the function TRANSLATE() for it. Unfortunately MySQL does not support it. And as far as I know no replacement for this function in MySQL exists currently. So using nested REPLACE() is probably the only option currently.
This is normal definition of some function as I know:
real function f(x)
real x
f = (sin(x))**2*exp(-x)
end function f
But I want to define a function from some string, for example the program will ask me to write it, and then it will define the function f in a program. Is this possible in Fortran?
What you are looking for is possible in reflective programming languages, and is not possible in Fortran.
Quote from the link above:
A language supporting reflection provides a number of features available at runtime that would otherwise be very obscure to accomplish in a lower-level language. Some of these features are the abilities to:
Discover and modify source code constructions (such as code blocks, classes, methods, protocols, etc.) as a first-class object at runtime.
Convert a string matching the symbolic name of a class or function into a reference to or invocation of that class or function.
Evaluate a string as if it were a source code statement at runtime.
Create a new interpreter for the language's bytecode to give a new meaning or purpose for a programming construct.
I worked on a project once that tried to achieve something similar. We read in a string that contained a string with named variables and mathematical operations (a function if you will). In this string the variables then got replaced by their numerical values and the terms were evaluated.
The basic idea is not to too difficult, but it requires a lot of string manipulations - and it is not a function in the context of a programming language.
We did it like this:
Recursively divide the string at +,-,/,*, but remember to honor brackets
If this is not possible (without violating bracketing), evaluate the remaining string:
Does it contain a mathematical expression like cos? Yes => recurse into arguments
No => evaluate the mathematical expression (no variables allowed, but they got replaced)
This works quite well, but it requires:
Splitting strings
Matching in strings
Replacing strings with other strings, etc.
This is not trivial to do in Fortran, so if you have other options (like calling an external tool/script that returns the value), I would look into that - especially if you are new to Fortran!