问题
I have a reference number of the following type DAA76647.1 which I want to convert unchanged to a string in Mathematica.
That is
myfn[DAA76647.1]
gives as output
"DAA76647.1"
Is there an easy way to do this? (The input cannot be a string and, other than conversion to a string, I do not want to change the input in any other way).
Update
ToString /@ {A1234, 1234.1, A1234 .5}
gives the following output (where I have simply entered everything from the keyboard)
{"A1234", "1234.1", "0.5 A1234"}
It appears that if what goes before the decimal point is alphanumeric, there is a problem.
Possible Workaround
Based on a suggested solution by David Carraher, a possible method is as follows:
ToString[# /.a_ b_ :> ToString[b] <> StringDrop[ToString[a], 1]] & /@ {A1234,
1234.1, A1234 .5}
giving as output:
{"A1234", "1234.1", "A1234.5"}
This seems to work OK provided that what comes after the decimal point is not alphanumeric, and provided that what comes before does not begin with zero (0A123.1, for example).
If alphanumerics occur only after the decimal point, this may be incorporated
StringReplace[ToString[123.45 B55c], Whitespace -> ""]
but if alphanumerics occur before and after the decimal point the number still needs to be entered as a string.
David Carraher's original suggestion
f[Times[a_, b_]] := ToString[b] <> ToString[a]
回答1:
If you enter DAA76647DAA76647.1 via an input cell in a Mma notebook, Mma will interpret the characters as a multiplication. It even automatically inserts a space between the 7 and the .1 (at least in Mma 8) when you input it.
DAA76647DAA76647 .1 // FullForm
(*Out= Times[0.1`,DAA76647DAA76647] *)
This looks promising:
f[Times[a_, b_]] := ToString[b] <> ToString[a]
EDIT: However, as TomD noted (and I somehow missed), it adds an additional zero to the solution!
f[Times[DAA76647DAA76647 .1]]
(*Out= DAA76647DAA766470.1 *)
%//FullForm
"DAA76647DAA766470.1"
TomD later showed how it is possible to handle this by StringDropping the zero.
This corrected solution will work if only numbers appear to the right of the decimal point and if the left-hand part is not interpreted as a product.
If you try to enter DAA76647.01A Mma will parse it as
(*Out= Times[".01",A,DAA76647] *)
Notice that it changes the order of the components.
I cannot see a way to handle this reordering.
回答2:
The call for myfn[DAA76647.1] should be intercepted at the stage of converting Input to an expression.
You can see that Input has the form RowBox[{"myfn", "[", RowBox[{"DAA76647", ".1"}], "]"}]:
In[1]:= myfn[DAA76647 .1]
DownValues[InString]
Out[1]= myfn[0.1 DAA76647]
Out[2]= {HoldPattern[InString[1]] :>
ToString[RowBox[{"myfn", "[", RowBox[{"DAA76647", ".1"}], "]"}],
InputForm],
HoldPattern[InString[2]] :>
ToString[RowBox[{"DownValues", "[", "InString", "]"}], InputForm]}
We could create a special case definition for MakeExpression:
MakeExpression[RowBox[{"myfn", "[", RowBox[{"DAA76647", ".1"}], "]"}],
f_] := MakeExpression[RowBox[{"myfn", "[", "\"DAA76647.1\"", "]"}],
f]
You can see that now myfn[DAA76647 .1] works as desired:
In[4]:= myfn[DAA76647 .1]//FullForm
Out[4]//FullForm= myfn["DAA76647.1"]
This approach can be generalized to something like
MakeExpression[RowBox[{"myfn", "[", expr:Except[_String], "]"}], form_] :=
With[{mexpr = StringJoin[expr /. RowBox -> List]}, Hold[myfn[mexpr]]]
myfn[expr_String] := (* what ever you want to do here *)
Note that the Except[_String] part is not really needed... since the following code won't do anything wrong with a String.
At the moment, the code only works with simple examples with one-dimensional box structure. If you want something that handles more general input, you might want to add error checking or extra rules for things like SuperscriptBox and friends. Or hit it with the hammer of Evaluate[Alternatives @@ Symbol /@ Names["*Box"]] -> List to make all Box objects become lists and flatten everything down.
回答3:
I don't think you can directly type this between the brackets of a function call, but would
myfn[InputString[]]
work for you?
来源:https://stackoverflow.com/questions/5597281/how-to-convert-an-alphanumeric-reference-number-containing-a-decimal-point-to